命令模式将请求封装为对象,实现调用者与接收者的解耦。1. Command接口定义execute方法;2. ConcreteCommand实现具体操作并绑定Receiver;3. Receiver执行实际动作;4. Invoker通过调用命令的execute发起请求;5. Client创建命令并绑定接收者。示例中遥控器(Invoker)通过LightOnCommand和LightOffCommand控制电灯(Receiver)的开关,支持扩展undo方法实现撤销功能,适用于GUI、任务调度等需参数化操作的场景。

在C++中,命令模式(Command Pattern)是一种行为设计模式,它将“请求”封装成对象,从而使你可以用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。
核心思想是:把一个操作(比如打开灯、保存文件)变成一个对象(命令对象),这个对象知道接收者和要执行的动作,并能执行该动作。调用者不需要知道具体执行细节,只需要调用命令的execute方法即可。
基本结构
命令模式通常包含以下几个角色:
- Command(命令接口):声明执行操作的接口,比如execute()
- ConcreteCommand(具体命令):实现Command接口,持有对“接收者”的引用,并在execute中调用接收者的相应方法
- Receiver(接收者):真正执行请求操作的对象,比如灯、文件处理器等
- Invoker(调用者):持有命令对象,通过调用命令的execute来发起请求
- Client(客户端):创建命令对象并绑定其接收者
代码示例
以下是一个简单的例子:用命令模式控制电灯的开关。
立即学习“C++免费学习笔记(深入)”;
#include#include // 接收者:电灯 class Light { public: void on() { std::cout << "Light is ON\n"; } void off() { std::cout << "Light is OFF\n"; } }; // 命令接口 class Command { public: virtual ~Command() = default; virtual void execute() = 0; }; // 具体命令:开灯 class LightOnCommand : public Command { Light& light; public: explicit LightOnCommand(Light& l) : light(l) {} void execute() override { light.on(); } }; // 具体命令:关灯 class LightOffCommand : public Command { Light& light; public: explicit LightOffCommand(Light& l) : light(l) {} void execute() override { light.off(); } }; // 调用者:遥控器 class RemoteControl { std::unique_ptr command; public: void setCommand(std::unique_ptr cmd) { command = std::move(cmd); } void pressButton() { if (command) { command->execute(); } } };
使用方式
在main函数中组装对象并运行:
int main() {
Light livingRoomLight;
// 创建具体命令
auto onCmd = std::make_unique(livingRoomLight);
auto offCmd = std::make_unique(livingRoomLight);
RemoteControl remote;
// 设置并执行开灯命令
remote.setCommand(std::move(onCmd));
remote.pressButton();
// 设置并执行关灯命令
remote.setCommand(std::move(offCmd));
remote.pressButton();
return 0;
}
扩展功能:支持撤销
命令模式很容易支持撤销操作。只需在Command接口中添加undo方法。
class Command {
public:
virtual ~Command() = default;
virtual void execute() = 0;
virtual void undo() = 0; // 新增撤销
};
// 修改 LightOnCommand 支持撤销
class LightOnCommand : public Command {
Light& light;
public:
explicit LightOnCommand(Light& l) : light(l) {}
void execute() override {
light.on();
}
void undo() override {
light.off();
}
};
// 类似地,LightOffCommand 的 undo 是开灯
void undo() override {
light.on();
}
RemoteControl 可以记录上一个命令,在用户按下“撤销”时调用undo。
优点与适用场景
命令模式的优势包括:
- 解耦调用者与接收者
- 支持命令队列、宏命令(组合多个命令)、延迟执行
- 实现撤销/重做非常方便
- 可以用于实现事务性操作
适用于需要将操作参数化、记录操作日志、支持撤销机制的系统,如GUI按钮、菜单项、任务调度等。
基本上就这些。通过将请求封装为对象,C++中的命令模式提升了系统的灵活性和扩展性。











