命令模式(Command pattern): 将”请求”封闭成对象, 以便使用不同的请求,队列或者日志来参数化其他对象. 命令模式也支持可撤销的操作。

意图

将命令封装成对象中,以便使用命令来参数化其它对象,或者将命令对象放入队列中进行排队,或者将命令对象的操作记录到日志中,以及支持可撤销的操作。

类图

  • Command: 命令
  • Receiver: 命令接收者,也就是命令真正的执行者
  • Invoker: 通过它来调用命令
  • Client: 可以设置命令与命令的接收者

image.png

实现

设计一个遥控器,可以控制电灯开关。
image.png

  1. public interface Command {
  2. void execute();
  3. }
  1. public class LightOnCommand implements Command {
  2. Light light;
  3. public LightOnCommand(Light light) {
  4. this.light = light;
  5. }
  6. @Override
  7. public void execute() {
  8. light.on();
  9. }
  10. }
  1. public class LightOffCommand implements Command {
  2. Light light;
  3. public LightOffCommand(Light light) {
  4. this.light = light;
  5. }
  6. @Override
  7. public void execute() {
  8. light.off();
  9. }
  10. }
  1. public class Light {
  2. public void on() {
  3. System.out.println("Light is on!");
  4. }
  5. public void off() {
  6. System.out.println("Light is off!");
  7. }
  8. }
  1. /**
  2. * 遥控器
  3. */
  4. public class Invoker {
  5. private Command[] onCommands;
  6. private Command[] offCommands;
  7. private final int slotNum = 7;
  8. public Invoker() {
  9. this.onCommands = new Command[slotNum];
  10. this.offCommands = new Command[slotNum];
  11. }
  12. public void setOnCommand(Command command, int slot) {
  13. onCommands[slot] = command;
  14. }
  15. public void setOffCommand(Command command, int slot) {
  16. offCommands[slot] = command;
  17. }
  18. public void onButtonWasPushed(int slot) {
  19. onCommands[slot].execute();
  20. }
  21. public void offButtonWasPushed(int slot) {
  22. offCommands[slot].execute();
  23. }
  24. }
  1. public class Client {
  2. public static void main(String[] args) {
  3. Invoker invoker = new Invoker();
  4. Light light = new Light();
  5. Command lightOnCommand = new LightOnCommand(light);
  6. Command lightOffCommand = new LightOffCommand(light);
  7. invoker.setOnCommand(lightOnCommand, 0);
  8. invoker.setOffCommand(lightOffCommand, 0);
  9. invoker.onButtonWasPushed(0);
  10. invoker.offButtonWasPushed(0);
  11. }
  12. }

JDK