Skip to content

命令模式

命令模式(Command Pattern)是一种行为设计模式,它将请求封装成对象,从而使您可以用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。命令模式通过将请求发送者和接收者解耦,提供了一种统一的方式来处理不同类型的请求。

命令模式的主要角色

  1. Command(命令接口):声明执行操作的接口。
  2. ConcreteCommand(具体命令类):实现 Command 接口,并定义一个接收者及绑定接收者的动作。
  3. Receiver(接收者):知道如何实施与执行一个请求相关的操作。任何类都可以作为接收者。
  4. Invoker(调用者/请求者):通过调用execute()方法来提交请求到命令对象。
  5. Client(客户端):创建具体的命令对象并设置其接收者。

在 JavaScript 中的实现

下面是一个简单的例子来说明如何在 JavaScript 中使用命令模式:

示例:电灯控制器

假设我们需要设计一个遥控器,用来控制电灯的开关状态。

javascript
// Command(命令接口)
class Command {
  execute() {
    throw new Error("This method should be overridden");
  }

  undo() {
    throw new Error("This method should be overridden");
  }
}

// Receiver(接收者)
class Light {
  constructor(name) {
    this.name = name;
  }

  on() {
    console.log(`${this.name} light is on`);
  }

  off() {
    console.log(`${this.name} light is off`);
  }
}

// ConcreteCommand(具体命令类)
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();
  }
}

// Invoker(调用者)
class RemoteControl {
  setCommand(command) {
    this.command = command;
  }

  pressButton() {
    this.command.execute();
  }

  pressUndo() {
    this.command.undo();
  }
}

// 使用示例
const livingRoomLight = new Light("Living Room");
const lightOn = new LightOnCommand(livingRoomLight);
const lightOff = new LightOffCommand(livingRoomLight);

const remote = new RemoteControl();

remote.setCommand(lightOn);
remote.pressButton(); // 输出: Living Room light is on

remote.setCommand(lightOff);
remote.pressButton(); // 输出: Living Room light is off

remote.pressUndo(); // 输出: Living Room light is on

代码解释

  • Command(命令接口):定义了两个方法 executeundo,分别用于执行命令和撤销命令。
  • Light(接收者):包含了实际执行命令的方法,如 onoff
  • LightOnCommand 和 LightOffCommand(具体命令类):实现了命令接口,并绑定了接收者的相应操作。
  • RemoteControl(调用者):负责调用命令的 execute 方法来执行命令,也可以调用 undo 方法来撤销命令。
  • 使用示例:展示了如何使用命令模式来控制电灯的开关状态,包括直接执行命令和撤销命令。

应用场景

命令模式适用于以下几种情况:

  • 当需要将一个请求封装为对象时,这样可以使用不同的请求对客户进行参数化。
  • 当需要将发出请求的对象和执行请求的对象解耦时。
  • 当需要支持取消操作时,命令模式可以通过存储历史命令来轻松实现撤销功能。
  • 当需要支持事务时,命令模式可以将多个命令组合成一个复合命令,并且可以原子性地执行这些命令。

通过使用命令模式,可以使系统更加灵活,易于扩展,并且能够方便地添加新的命令类型而无需修改现有代码。此外,命令模式还支持命令队列、日志记录和事务等功能。

Released under the MIT License.