命令模式:将请求封装为一个对象,从而可以将不同的请求作为参数来传递。对请求排队或记录日志,以及支持可撤销的操作。
命令模式
命令模式 Command Pattern
:类似系统菜单,比如开机、关机、重启、注销等等,这些动作都封装成命令对象,作为参数记录并执行。
命令模式可以对发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求,这就是命令模式的模式动机。
类图结构
结构解析
Command
接口,定义所有的命令。
ConcreteCommand
实现类,具体不同的命令。
Invoker
请求者,也是命令发送者,记录命令并做出具体的命令请求。
Receiver
接收者,接收命令并执行具体的命令。
Client
客户端。
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| public interface Command { void execute(); }
public class FlipUpCommand implements Command { private Receiver receiver;
public FlipUpCommand(Receiver receiver) { this.receiver = receiver; }
@Override public void execute() { receiver.turnOn(); } }
public class FlipDownCommand implements Command { private Receiver receiver;
public FlipDownCommand(Receiver receiver) { this.receiver = receiver; }
@Override public void execute() { receiver.turnOff(); } }
public class Invoker { private List<Command> commands = new ArrayList<>();
public void add(Command command){ commands.add(command); }
public void execute(Command command){ if (!commands.contains(command)){ add(command); }else { command.execute(); } }
public void remove(Command command){ commands.remove(command); } }
public class Receiver {
public void turnOn(){ System.out.println("Receiver, Light: turn On."); }
public void turnOff(){ System.out.println("Receiver, Light: turn Off."); } }
public class TestCommand { public static void main(String[] args) { Receiver light = new Receiver();
FlipUpCommand upCommand = new FlipUpCommand(light); FlipDownCommand downCommand = new FlipDownCommand(light);
Invoker invoker = new Invoker(); invoker.add(upCommand); invoker.add(downCommand);
invoker.execute(upCommand); invoker.remove(downCommand); } }
Receiver, Light: turn On.
|
总结
命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开,降低了系统耦合度,同时很容易增加新命令,但是会导致过多的具体命令类。
参考文档
- 大话设计模式
Android
源码设计模式解析与实战
- 命令模式