简介
在 JavaScript 中,命令模式是一种行为设计模式,它将请求封装为一个对象,从而允许你用不同的请求、队列或者日志来参数化其他对象,支持可撤销的操作
。命令模式的核心思想是将请求的发送者和接收者解耦,使得发送者不需要知道具体的接收者是谁以及具体的操作是什么
。
命令模式的核心概念
- 命令(Command):定义了执行请求的接口。在 JavaScript 中,这通常是一个包含 execute 方法的类或者对象。
- 具体命令(Concrete Command):实现命令接口,定义具体的执行操作。
- 接收者(Receiver):执行请求的对象。
- 调用者(Invoker):负责调用命令对象执行请求。
- 客户(Client):创建具体的命令对象,并设置它们的接收者。
使用场景
- 需要对操作进行参数化。
- 需要将操作排队执行。
- 需要支持操作的撤销和重做。
实现命令模式
-
例子:遥控器控制家电
假设有一个简单的遥控器,可以控制灯和音响的开关操作。我们将使用命令模式来实现这一功能// 命令接口 class Command { execute() {} undo() {} } // 具体命令:打开灯 class LightOnCommand extends Command { constructor(light) { super(); this.light = light; } execute() { this.light.on(); } undo() { this.light.off(); } } // 具体命令:关闭灯 class LightOffCommand extends Command { constructor(light) { super(); this.light = light; } execute() { this.light.off(); } undo() { this.light.on(); } } // 接收者:灯 class Light { on() { console.log("The light is on"); } off() { console.log("The light is off"); } } // 具体命令:打开音响 class StereoOnCommand extends Command { constructor(stereo) { super(); this.stereo = stereo; } execute() { this.stereo.on(); } undo() { this.stereo.off(); } } // 具体命令:关闭音响 class StereoOffCommand extends Command { constructor(stereo) { super(); this.stereo = stereo; } execute() { this.stereo.off(); } undo() { this.stereo.on(); } } // 接收者:音响 class Stereo { on() { console.log("The stereo is on"); } off() { console.log("The stereo is off"); } } // 调用者:遥控器 class RemoteControl { constructor() { this.commands = []; } setCommand(command) { this.commands.push(command); command.execute(); } undoCommand() { const command = this.commands.pop(); if (command) { command.undo(); } } } // 客户端代码 const light = new Light(); const stereo = new Stereo(); const lightOn = new LightOnCommand(light); const lightOff = new LightOffCommand(light); const stereoOn = new StereoOnCommand(stereo); const stereoOff = new StereoOffCommand(stereo); const remoteControl = new RemoteControl(); // 执行命令 remoteControl.setCommand(lightOn); remoteControl.setCommand(stereoOn); // 撤销操作 remoteControl.undoCommand(); remoteControl.undoCommand();
在这个示例中:
- Command 类定义了命令接口。
- LightOnCommand 和 LightOffCommand 类实现了具体的灯控制命令。
- StereoOnCommand 和 StereoOffCommand 类实现了具体的音响控制命令。
- Light 和 Stereo 类分别是灯和音响的接收者。
- RemoteControl 类是调用者,负责存储和执行命令。
- 客户端代码创建了具体的命令对象,并通过遥控器执行和撤销这些命令
总结
JavaScript 中的命令模式通过将请求封装为对象,实现了请求发送者与接收者的解耦
。这种模式非常适合需要对操作进行参数化、排队执行或支持撤销和重做功能的场景
。通过命令对象的抽象,系统可以灵活地扩展和维护,增强了代码的可读性和可
。