命令模式


概述

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

结构图

代码实现

命令

    /// 
    /// 抽象命令类
    /// 
   public abstract class Command
    {
        protected Receiver receiver;

        public Command(Receiver receiver)
        {
            this.receiver = receiver;
        }

        abstract public void Execute();
    }
    /// 
    /// 具体命令实现
    /// 
    public class ConcreteCommand : Command
    {
        public ConcreteCommand(Receiver receiver) : base(receiver)
        { }

        public override void Execute()
        {
            receiver.Action();
        }
    }

请求者

    /// 
    /// 请求者/调用者
    /// 
    public class Invoker
    {
        private Command command;

        public void SetCommand(Command command)
        {
            this.command = command;
        }

        public void ExecuteCommand()
        {
            command.Execute();
        }
    }

接收者

    /// 
    /// 抽象接收者/实现者
    /// 
    public abstract class Receiver
    {
        public abstract void Action();
    }
    /// 
    /// 接收者A/实现者A
    /// 
    public class ReceiverA: Receiver
    {
        public override void Action()
        {
            Console.WriteLine("A执行请求!");
        }
    }
    /// 
    /// 接收者B/实现者B
    /// 
    public class ReceiverB : Receiver
    {
        public override void Action()
        {
            Console.WriteLine("B执行请求!");
        }
    }

客户端

    class Program
    {
        static void Main(string[] args)
        {
            Receiver rA = new ReceiverA();
            Command cA = new ConcreteCommand(rA);
            Receiver rB = new ReceiverB();
            Command cB = new ConcreteCommand(rB);
            Invoker i = new Invoker();
            i.SetCommand(cA);
            i.ExecuteCommand();
            i.SetCommand(cB);
            i.ExecuteCommand();

            Console.Read();
        }
    }

运行结果

优势

降低了系统耦合度。扩展性良好,增加或删除命令非常方便。采用命令模式增加与删除命令不会影响其他类,且满足“开闭原则”。

新的命令可以很容易添加到系统中去。

使用场景

软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时。

当系统的某项操作具备命令语义,且命令实现不稳定(变化)时,可以通过命令模式解耦请求与实现。

请求调用者需要与请求接收者解耦时,命令模式可以使调用者和接收者不直接交互。

缺陷

使用命令模式可能会导致某些系统有过多的具体命令类。

Demo