zoukankan      html  css  js  c++  java
  • 设计模式之命令模式

    名词解释:

    命令模式:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作.

    必要元素:

    1.用于执行操作的接口(抽象类);
    2.一个或者多个实现(继承)自操作接口的类;
    3.用于执行命令的类;
    4.接收者,用于实施与请求相关的操作。

    上例子:

    命令接口:

     abstract class Command
        {
            protected Receiver receiver;
            public Command(Receiver receiver)
            {
                this.receiver = receiver;
            }
            public abstract void Execute();
        }

    接口实现类:

     class ConcreteCommand : Command
        {
            public ConcreteCommand(Receiver receiver)
                : base(receiver)
            { }
    
            public override void Execute()
            {
                receiver.Action();
            }
        }

    执行请求类(接收者,也就是命令执行的操作就是该类的行为):

     class Receiver
        {
            public void Action()
            {
                Console.WriteLine("执行请求!");
            }
        }

    执行命令类:

     class Invoker
        {
            private Command command;
            public void SetCommand(Command command)
            {
                this.command = command;
            }
            public void ExecuteCommand()
            {
                command.Execute();
            }
        }

    调用:

            Receiver r = new Receiver();
                Command c = new ConcreteCommand(r);
                Invoker i = new Invoker();
    
                i.SetCommand(c);
                i.ExecuteCommand();
    
                Console.Read();

     例子二(由于上述例子只是代码的构成部分,通过一个厨师做羊肉串和炸鸡翅,以及服务员向顾客询问点餐,这样一个场景):

    抽象命令:

     abstract class Command
        {
            protected Barbecuer receiver;
            public Command(Barbecuer receiver)
            {
                this.receiver=receiver;
            }
    
            public abstract void ExecuteCommand();
        }

    具体命令:

       /// <summary>
        /// 烤鸡翅命令
        /// </summary>
        class BakeChickenWingCommand:Command
        {
            public BakeChickenWingCommand(Barbecuer receiver)
                : base(receiver) { }
            public override void ExecuteCommand()
            {
                receiver.BakeChickenWing();
            }
        }
    
    
       /// <summary>
        /// 羊肉串命令
        /// </summary>
        class BakeMuttonCommand:Command
        {
            public BakeMuttonCommand(Barbecuer receiver)
                : base(receiver)
            { }
            public override void ExecuteCommand()
            {
                receiver.BakeMutton();
            }
        }

    厨师类(也就是执行请求类):

      class Barbecuer
        {
            public void BakeMutton()
            {
                Console.WriteLine("烤羊肉串!");
            }
    
            public void BakeChickenWing()
            {
                Console.WriteLine("烤鸡翅!");
            }
        }

    服务员类(执行命令):

     class Waiter
        {
            private IList<Command> orders=new  List<Command>();
    
            public void SetCommand(Command command)
            {
                orders.Add(command);
                Console.WriteLine("增加订单:"+command.ToString()+"  时间:"+DateTime.Now.ToString());
            }
    
            public void CancelOrder(Command command)
            {
                orders.Remove(command);
                Console.WriteLine("取消订单:" + command.ToString() + "  时间:" + DateTime.Now.ToString());
            }
    
            public void Notify()
            {
                foreach (var command in orders)
                {
                    command.ExecuteCommand();
                }
            }
        }

    调用:

                Barbecuer boy = new Barbecuer();
                Command bakeMuttonCommand1 = new BakeMuttonCommand(boy);
                Command bakeMuttonCommand2 = new BakeMuttonCommand(boy);
                Command bakeChickenWingCommand1 = new BakeChickenWingCommand(boy);
    
                Waiter girl = new Waiter();
                girl.SetCommand(bakeMuttonCommand1);
                girl.SetCommand(bakeMuttonCommand2);
                girl.SetCommand(bakeChickenWingCommand1);
    
                girl.Notify();
    
                Console.Read();

    整个过程和我们的必要元素是一一对应的,在Command中依赖Receiver(也就是真正执行命令的),在Invoke(Waiter也就是服务员,可以进行命令的增加和移除,实现命令队列)中也是放入Command进行命令的执行。最终的调用过程也是一层层的进行设置,不管是Receiver的设置还是Command的增加移除。

    总结:

     命令模式的优点:较容易实现一个命令队列;容易将命令记入日志;容易实现对请求的撤销和重做;增加新命令也较容易。

  • 相关阅读:
    php程序员的弱点
    php cli 模式下执行文件,require 加载路径错误
    第一次!
    IO流(一)之IO流综述
    异常和错误
    Comparable与Comparator比较分析
    Collection与Map学习笔记(三)
    两个对象比较
    Collection与Map学习笔记(二)
    包装类、及装箱和拆箱
  • 原文地址:https://www.cnblogs.com/ListenFly/p/3325145.html
Copyright © 2011-2022 走看看