设计模式之命令模式

名词解释:

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

必要元素:

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的增加移除。

总结:

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

原文地址:https://www.cnblogs.com/ListenFly/p/3325145.html