JavaScript 命令模式
介绍
命令模式是一种行为设计模式,它将请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销操作。简单来说,它将"请求"封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象,同时支持可撤销的操作。
命令模式的核心思想是将动作请求者与动作执行者解耦。
提示
命令模式的关键点在于:将命令(操作)封装成一个对象,这个对象包含了执行命令的所有信息。
命令模式的基本结构
命令模式主要包含以下几个角色:
- 命令(Command):声明执行操作的接口。
- 具体命令(ConcreteCommand):实现命令接口,通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。
- 接收者(Receiver):知道如何实施与执行一个请求相关的操作。
- 调用者(Invoker):要求命令对象执行请求。
- 客户端(Client):创建具体命令对象并设定它的接收者。
JavaScript 中的命令模式实现
在JavaScript中,由于其函数式特性,实现命令模式会比较灵活。下面通过一个简单的例子来说明:
// 接收者
class Light {
constructor(location) {
this.location = location;
this.status = "off";
}
turnOn() {
this.status = "on";
console.log(`${this.location} light is now ${this.status}`);
}
turnOff() {
this.status = "off";
console.log(`${this.location} light is now ${this.status}`);
}
}
// 命令接口(JavaScript中可以省略,这里为了说明概念)
class Command {
execute() {}
undo() {}
}
// 具体命令 - 开灯命令
class TurnOnCommand {
constructor(light) {
this.light = light;
}
execute() {
this.light.turnOn();
}
undo() {
this.light.turnOff();
}
}
// 具体命令 - 关灯命令
class TurnOffCommand {
constructor(light) {
this.light = light;
}
execute() {
this.light.turnOff();
}
undo() {
this.light.turnOn();
}
}
// 调用者 - 遥控器
class RemoteControl {
constructor() {
this.command = null;
}
setCommand(command) {
this.command = command;
}
pressButton() {
this.command.execute();
}
pressUndoButton() {
this.command.undo();
}
}
// 客户端代码
const bedroomLight = new Light("Bedroom");
const kitchenLight = new Light("Kitchen");
const turnOnBedroomLight = new TurnOnCommand(bedroomLight);
const turnOffBedroomLight = new TurnOffCommand(bedroomLight);
const turnOnKitchenLight = new TurnOnCommand(kitchenLight);
const turnOffKitchenLight = new TurnOffCommand(kitchenLight);
// 使用遥控器控制灯
const remote = new RemoteControl();
// 打开卧室灯
remote.setCommand(turnOnBedroomLight);
remote.pressButton(); // 输出: Bedroom light is now on
// 关闭卧室灯
remote.setCommand(turnOffBedroomLight);
remote.pressButton(); // 输出: Bedroom light is now off
// 打开厨房灯
remote.setCommand(turnOnKitchenLight);
remote.pressButton(); // 输出: Kitchen light is now on
// 撤销上一个操作(关闭厨房灯)
remote.pressUndoButton(); // 输出: Kitchen light is now off