结构

命令模式

说明

This pattern encapsulates a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.

这个模式将请求封装成一个对象, 从而可以不用的请求对客户进行参数化, 对请求排队或者记录请求日志, 以及支持可以取消的操作。

适用条件

  1. 行为需要扩充, 将命令作为对象处理, 新的行为可以通过扩充子类完成;
  2. 命令需要重做, 需要 UnDo 和 ReDo 的情况;
  3. 日志记录, 命令需要日志记录;
  4. 命令队列, 需要命令支持队列执行。

实现

public interface ICommand {

   void Execute();

}

public class Receiver {
      
   public void Action() {
      Console.WriteLine("Receiver Action.");
   }

}

public class ConcreteCommand : ICommand {

   private readonly Receiver _receiver;
   private object _state;

   public ConcreteCommand(Receiver receiver) {
      this._receiver = receiver;
   }

   public void Execute() {
      this._receiver.Action();
   }

}

public class Invoker {
      
   private readonly IList<ICommand> _commandHistory = new List<ICommand>();

   public void InvokeCommand(ICommand command) {
      command.Execute();
      this._commandHistory.Add(command);
   }
}

class Client {
      
   static void Main(string[] args) {

      var invoker = new Invoker();

      var receiver = new Receiver();
      ICommand command = new ConcreteCommand(receiver);
         
      invoker.InvokeCommand(command);

      Console.ReadKey();
   }
}

以下是维基百科上给出的 Java 实现

/*the Command interface*/
public interface Command {
   void execute();
}
 
 
/*the Invoker class*/
import java.util.List;
import java.util.ArrayList;
 
public class Switch {
 
   private List<Command> history = new ArrayList<Command>();
 
   public Switch() {
   }
 
   public void storeAndExecute(Command cmd) {
      this.history.add(cmd); // optional 
      cmd.execute();        
   }
 
}
 
 
/*the Receiver class*/
public class Light {
 
   public Light() {
   }
 
   public void turnOn() {
      System.out.println("The light is on");
   }
 
   public void turnOff() {
      System.out.println("The light is off");
   }
 
}
 
 
/*the Command for turning on the light - ConcreteCommand #1*/
public class FlipUpCommand implements Command {
 
   private Light theLight;
 
   public FlipUpCommand(Light light) {
      this.theLight = light;
   }
 
   public void execute(){
      theLight.turnOn();
   }
 
}
 
 
/*the Command for turning off the light - ConcreteCommand #2*/
public class FlipDownCommand implements Command {
 
   private Light theLight;
 
   public FlipDownCommand(Light light) {
      this.theLight = light;
   }
 
   public void execute() {
      theLight.turnOff();
   }
 
}
 
 
/*The test class or client*/
public class PressSwitch {
 
   public static void main(String[] args){
      Light lamp = new Light();
      Command switchUp = new FlipUpCommand(lamp);
      Command switchDown = new FlipDownCommand(lamp);
 
      Switch s = new Switch();
 
      try {
         if (args[0].equalsIgnoreCase("ON")) {
            s.storeAndExecute(switchUp);
            System.exit(0);
         }
         if (args[0].equalsIgnoreCase("OFF")) {
            s.storeAndExecute(switchDown);
            System.exit(0);
         }
         System.out.println("Argument \"ON\" or \"OFF\" is required.");
      } catch (Exception e) {
         System.out.println("Argument's required.");
      }
   }

}