命令模式:封装请求,轻松实现解耦!
大家好!本日我们来聊聊计划模式中的命令模式(Command Pattern)。如果你曾经需要将请求封装成对象,大概盼望实现请求的取消、重做等功能,那么命令模式就是你的不二之选!本文基于《Head First 计划模式》的命令模式章节,通过生动的故事和 Java 代码示例,带你轻松掌握命令模式的英华。
1. 命令模式是什么?
命令模式是一种举动型计划模式,它将请求封装成对象,从而使你可以用不同的请求对客户进行参数化,并支持请求的列队、记录日志、取消等操纵。命令模式的核心头脑是解耦请求的发送者和接收者,使得系统更加灵活和可扩展。
实用场景
- 需要将请求封装成对象,以便在不同的上下文中利用。
- 需要支持请求的取消、重做、列队等功能。
- 需要解耦请求的发送者和接收者。
2. 命令模式的实现
故事背景
小明开辟了一个智能家居系统,系统中有一个遥控器(RemoteControl)类,用于控制各种家电装备,比如灯(Light)、风扇(Fan)等。每个装备都有不同的操纵,比如打开、关闭、调节亮度等。
问题出现
如果直接在遥控器中调用装备的方法,会导致遥控器和装备之间的耦合度过高。此外,如果需要支持取消操纵,代码会变得非常复杂。
解决方案:命令模式
小明决定利用命令模式,将每个操纵封装成一个命令对象,从而解耦遥控器和装备。
代码实现
1. 界说命令接口
- // 命令接口
- interface Command {
- void execute();
- void undo();
- }
复制代码 2. 实现具体命令
- // 具体命令:打开灯
- class LightOnCommand implements Command {
- private Light light;
- public LightOnCommand(Light light) {
- this.light = light;
- }
- @Override
- public void execute() {
- light.on();
- }
- @Override
- public void undo() {
- light.off();
- }
- }
- // 具体命令:关闭灯
- class LightOffCommand implements Command {
- private Light light;
- public LightOffCommand(Light light) {
- this.light = light;
- }
- @Override
- public void execute() {
- light.off();
- }
- @Override
- public void undo() {
- light.on();
- }
- }
- // 具体命令:打开风扇
- class FanOnCommand implements Command {
- private Fan fan;
- public FanOnCommand(Fan fan) {
- this.fan = fan;
- }
- @Override
- public void execute() {
- fan.on();
- }
- @Override
- public void undo() {
- fan.off();
- }
- }
- // 具体命令:关闭风扇
- class FanOffCommand implements Command {
- private Fan fan;
- public FanOffCommand(Fan fan) {
- this.fan = fan;
- }
- @Override
- public void execute() {
- fan.off();
- }
- @Override
- public void undo() {
- fan.on();
- }
- }
复制代码 3. 界说装备类
- // 灯类
- class Light {
- public void on() {
- System.out.println("Light is on");
- }
- public void off() {
- System.out.println("Light is off");
- }
- }
- // 风扇类
- class Fan {
- public void on() {
- System.out.println("Fan is on");
- }
- public void off() {
- System.out.println("Fan is off");
- }
- }
复制代码 4. 实现遥控器
- // 遥控器类
- class RemoteControl {
- private Command[] onCommands;
- private Command[] offCommands;
- private Command undoCommand;
- public RemoteControl() {
- onCommands = new Command[2];
- offCommands = new Command[2];
- Command noCommand = new NoCommand();
- for (int i = 0; i < 2; i++) {
- onCommands[i] = noCommand;
- offCommands[i] = noCommand;
- }
- undoCommand = noCommand;
- }
- public void setCommand(int slot, Command onCommand, Command offCommand) {
- onCommands[slot] = onCommand;
- offCommands[slot] = offCommand;
- }
- public void onButtonWasPushed(int slot) {
- onCommands[slot].execute();
- undoCommand = onCommands[slot];
- }
- public void offButtonWasPushed(int slot) {
- offCommands[slot].execute();
- undoCommand = offCommands[slot];
- }
- public void undoButtonWasPushed() {
- undoCommand.undo();
- }
- }
- // 空命令类
- class NoCommand implements Command {
- @Override
- public void execute() {
- System.out.println("No command assigned");
- }
- @Override
- public void undo() {
- System.out.println("No command assigned");
- }
- }
复制代码 5. 客户端代码
- public class SmartHomeApp {
- public static void main(String[] args) {
- // 创建设备
- Light livingRoomLight = new Light();
- Fan livingRoomFan = new Fan();
- // 创建命令
- Command lightOn = new LightOnCommand(livingRoomLight);
- Command lightOff = new LightOffCommand(livingRoomLight);
- Command fanOn = new FanOnCommand(livingRoomFan);
- Command fanOff = new FanOffCommand(livingRoomFan);
- // 创建遥控器
- RemoteControl remoteControl = new RemoteControl();
- remoteControl.setCommand(0, lightOn, lightOff);
- remoteControl.setCommand(1, fanOn, fanOff);
- // 操作遥控器
- remoteControl.onButtonWasPushed(0); // 输出: Light is on
- remoteControl.offButtonWasPushed(0); // 输出: Light is off
- remoteControl.undoButtonWasPushed(); // 输出: Light is on
- remoteControl.onButtonWasPushed(1); // 输出: Fan is on
- remoteControl.offButtonWasPushed(1); // 输出: Fan is off
- remoteControl.undoButtonWasPushed(); // 输出: Fan is on
- }
- }
复制代码 3. 命令模式的长处
- 解耦请求的发送者和接收者
命令模式将请求封装成对象,使得请求的发送者和接收者之间没有直接的依赖关系。
- 支持取消和重做
通过实现 undo() 方法,可以轻松实现取消操纵。
- 支持请求的列队和日志记录
命令对象可以被存储、传递和记录,从而支持请求的列队和日志记录。
- 易于扩展
新增命令时,只需实现新的命令类,无需修改现有代码。
4. 总结
命令模式通过将请求封装成对象,实现了请求的发送者和接收者之间的解耦,从而使得系统更加灵活和可扩展。通过本文的讲授和代码示例,信赖你已经掌握了命令模式的核心头脑和实现方法。在实际开辟中,命令模式非常适实用于实现取消、重做、列队等功能。
互动话题
你在项目中用过命令模式吗?遇到过哪些问题?欢迎在批评区分享你的经验!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |