命令模式是一种行为设计模式,它将一个请求封装成一个对象,从而让你使用不同的请求、队列或者请求的日志来参数化其他对象。它也支持可撤销的操作。命令模式的关键是引入了抽象层——命令接口,具体命令实现该接口,执行操作的对象从执行具体操作的职责中解耦出来。
接收者类Light实际执行与请求相关的操作:
- public class Light {
- public void turnOn() {
- System.out.println("Light is on");
- }
-
- public void turnOff() {
- System.out.println("Light is off");
- }
- }
命令接口定义了执行操作的方法:
- public interface Command {
- void execute();
- }
具体命令实现命令接口,并定义接收者和操作之间的绑定关系:
- public class LightOnCommand implements Command {
- private Light light;
-
- public LightOnCommand(Light light) {
- this.light = light;
- }
-
- @Override
- public void execute() {
- light.turnOn();
- }
- }
-
- public class LightOffCommand implements Command {
- private Light light;
-
- public LightOffCommand(Light light) {
- this.light = light;
- }
-
- @Override
- public void execute() {
- light.turnOff();
- }
- }
调用者持有命令对象,并在某个时间点调用命令对象的execute()方法:
- public class RemoteControl {
- private Command command;
-
- public void setCommand(Command command) {
- this.command = command;
- }
-
- public void pressButton() {
- if (command != null) {
- command.execute();
- }
- }
- }
客户端决定哪个命令执行,以及它的接收者是谁:
- public class Client {
- public static void main(String[] args) {
- // 创建接收者
- Light light = new Light();
-
- // 创建命令,并设置其接收者
- Command lightsOn = new LightOnCommand(light);
- Command lightsOff = new LightOffCommand(light);
-
- // 创建调用者,并关联命令
- RemoteControl control = new RemoteControl();
- control.setCommand(lightsOn); // 设置开灯命令
- control.pressButton(); // 执行开灯命令
-
- control.setCommand(lightsOff); // 设置关灯命令
- control.pressButton(); // 执行关灯命令
- }
- }
通过这个更完整的示例,我们可以看到命令模式的几个关键好处:
RemoteControl(调用者)不直接操作Light(接收者),而是通过命令对象进行间接操作。这意味着Light类的任何变化都不会直接影响到RemoteControl类,反之亦然。Command实现即可,无需修改现有的Invoker或Receiver类。这样,使用命令模式提供了代码的灵活性和扩展性,同时也使得操作的撤销和重做成为可能。