1 命令模式
概念
- 命令模式(Command Pattern):将一个请求封装为一个对象,可用不同的请求对客户进行参数化。对请求排队或者记录请求日记,以及支持可撤销的操作。又称为动作(Action)模式或事务(Transaction)模式。
- 命令模式可以将请求发送者和接受者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不知道如何完成请求。
- 命令模式的关键在于引入了抽象命令类,请求发送者针对抽象命令类编程,只有实现了抽象命令类的具体命令才与请求接收者相关联。

- 抽象命令类(Command):一个抽象类或接口,声明了用于执行请求的execute()等方法。这些方法可以调用请求接收者(Receiver)的相关操作。
- 具体的命令类(ConcreteCommand):Command的子类,实现了其声明的方法对于具体的Recever的对象,讲Receiver对象的动作绑定其中。在其实现execute()方法时,将调用Receiver对象的相关操作。
- 调用者(Invoker):请求的发送者,通过命令对象来执行请求。Invoker并不需要在设计时确定其接收者。与Command之间存在关联关系,程序运行的时候,将一个具体的命令对象注入其中,调用其execute()方法,从而实现间接调用请求接收者的相关操作。
- 接收者(Receiver):执行请求相关操作,它具体实现对请求的业务处理。
适用场景
- 系统需要将请求调用者和请求接受者解耦。请求者无须知道接收者,接受者也无须关心何时被调用。
- 系统需要在不同的时间指定请求、将请求排队和执行请求。
- 需要支持命令的撤销和恢复操作。
- 将一组操作组合在一起形成宏命令。
优点
降低系统的耦合度;新的命令可以很容易地加入到系统中;比较容易地设计一个命令队列或宏命令(组合命令);为请求的撤销和恢复操作提供了一种设计和实现方案。
缺点
导致某些系统有过多的具体命令类。
2 案例
抽象命令类
public interface Command {
public void execute();
public void undo();
}
具体命令类
LightOnCommand
public class LightOnCommand implements Command {
LightReceiver light;
public LightOnCommand(LightReceiver light) {
super();
this.light = light;
}
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
light.off();
}
}
LightOffCommand
public class LightOffCommand implements Command {
LightReceiver light;
public LightOffCommand(LightReceiver light) {
super();
this.light = light;
}
@Override
public void execute() {
light.off();
}
@Override
public void undo() {
light.on();
}
}
接收者
public class LightReceiver {
public void on() {
System.out.println(" 电灯打开了.. ");
}
public void off() {
System.out.println(" 电灯关闭了.. ");
}
}
RemoteController
public class RemoteController {
Command[] onCommands;
Command[] offCommands;
Command undoCommand;
public RemoteController() {
onCommands = new Command[5];
offCommands = new Command[5];
for (int i = 0; i < 5; i++) {
onCommands[i] = new NoCommand();
offCommands[i] = new NoCommand();
}
}
public void setCommand(int no, Command onCommand, Command offCommand) {
onCommands[no] = onCommand;
offCommands[no] = offCommand;
}
public void onButtonWasPushed(int no) {
onCommands[no].execute();
undoCommand = onCommands[no];
}
public void offButtonWasPushed(int no) {
offCommands[no].execute();
undoCommand = offCommands[no];
}
public void undoButtonWasPushed() {
undoCommand.undo();
}
}
调用者
public class Client {
public static void main(String[] args) {
LightReceiver lightReceiver = new LightReceiver();
LightOnCommand lightOnCommand = new LightOnCommand(lightReceiver);
LightOffCommand lightOffCommand = new LightOffCommand(lightReceiver);
RemoteController remoteController = new RemoteController();
remoteController.setCommand(0, lightOnCommand, lightOffCommand);
System.out.println("--------按下灯的开按钮-----------");
remoteController.onButtonWasPushed(0);
System.out.println("--------按下灯的关按钮-----------");
remoteController.offButtonWasPushed(0);
System.out.println("--------按下撤销按钮-----------");
remoteController.undoButtonWasPushed();
}
}