1、命令模式的学习
当你想要将请求与实际执行操作的对象解耦时,可以使用命令模式。它将一个请求封装为一个对象,从而使你可以根据不同的请求将其参数化,将请求队列或日志请求,并支持可撤销的操作。
命令模式由以下几个核心角色组成:
- 命令(Command):定义了执行操作的接口,并包含执行操作所需的方法。
- 具体命令(Concrete Command):实现了命令接口,负责执行具体的操作。
- 接收者(Receiver):执行实际操作的对象。它知道如何执行命令相关的操作。
- 调用者(Invoker):负责调用命令对象来执行请求。它只知道如何调用命令,而不知道命令执行的具体细节。
- 客户端(Client):创建具体命令对象并设置其接收者。
2、命令模式的使用
假设有一个电灯类 Light,其中有打开灯和关闭灯的方法。请使用命令模式设计一个灯控制器,该控制器可以接收不同的命令并执行相应的操作,包括打开灯、关闭灯以及撤销上一次操作。
接收者
public class Light {public void turnOn() {System.out.println("电灯已打开");}public void turnOff() {System.out.println("电灯已关闭");}
}
抽象命令
public interface LightCommand {/*** 打开电灯*/void turnOn();/*** 关闭电灯*/void turnOff();/*** 撤销上一步*/void undo();
}
具体命令
public class LightCommandImpl implements LightCommand {private Light light;private String lastStatus;public LightCommandImpl(Light light) {this.light = light;}@Overridepublic void turnOn() {light.turnOn();lastStatus = "已打开";}@Overridepublic void turnOff() {light.turnOff();lastStatus = "已关闭";}@Overridepublic void undo() {if (StringUtils.isNotBlank(lastStatus)) {lastStatus = "已关闭".equals(lastStatus) ? "已打开" : "已关闭";}System.out.println("撤销:" + lastStatus + "操作");}
}
调用者
public class LightControl {private LightCommand lightCommand;public LightControl(LightCommand lightCommand) {this.lightCommand = lightCommand;}public void turnOn() {lightCommand.turnOn();}public void turnOff() {lightCommand.turnOff();}public void undo() {lightCommand.undo();}
}
客户端
public class LightClient {public static void main(String[] args) {Light light = new Light();LightCommand lightCommand = new LightCommandImpl(light);LightControl lightControl = new LightControl(lightCommand);lightControl.turnOn();lightControl.turnOff();lightControl.undo();}
}
电灯已打开
电灯已关闭
撤销:已打开操作
3、总结
这里的 Light 类充当了接收者角色,负责实际执行操作。LightCommand 接口定义了命令的操作方法,并有具体的实现类 LightCommandImpl 实现了该接口,将命令操作委托给 Light 类。LightControl 类充当了请求者角色,用于接收命令并执行相应的操作。