目录
命令模式是一种行为型设计模式,它将一个请求封装成一个对象,从而使您可以用不同的请求对客户端进行参数化、对请求排队或记录请求日志,以及支持可撤销的操作。命令模式将请求的发出者和执行者解耦,使得请求的发送者无需知道执行请求的具体操作。
命令模式来实现控制各种设备(如灯、电视、空调)。
- #include
- #include
- #include
-
- // 命令接口
- class Command {
- public:
- virtual ~Command() = default;
- virtual void execute() = 0;
- };
-
- // 接收者:灯
- class Light {
- public:
- void on() {
- std::cout << "Light is ON\n";
- }
- void off() {
- std::cout << "Light is OFF\n";
- }
- };
-
- // 接收者:电视
- class TV {
- public:
- void on() {
- std::cout << "TV is ON\n";
- }
- void off() {
- std::cout << "TV is OFF\n";
- }
- };
-
- // 接收者:空调
- class AirConditioner {
- public:
- void on() {
- std::cout << "AirConditioner is ON\n";
- }
- void off() {
- std::cout << "AirConditioner is OFF\n";
- }
- };
-
- // 具体命令:打开灯
- class LightOnCommand : public Command {
- private:
- Light& light;
- public:
- LightOnCommand(Light& light) : light(light) {}
- void execute() override {
- light.on();
- }
- };
-
- // 具体命令:关闭灯
- class LightOffCommand : public Command {
- private:
- Light& light;
- public:
- LightOffCommand(Light& light) : light(light) {}
- void execute() override {
- light.off();
- }
- };
-
- // 具体命令:打开电视
- class TVOnCommand : public Command {
- private:
- TV& tv;
- public:
- TVOnCommand(TV& tv) : tv(tv) {}
- void execute() override {
- tv.on();
- }
- };
-
- // 具体命令:关闭电视
- class TVOffCommand : public Command {
- private:
- TV& tv;
- public:
- TVOffCommand(TV& tv) : tv(tv) {}
- void execute() override {
- tv.off();
- }
- };
-
- // 具体命令:打开空调
- class AirConditionerOnCommand : public Command {
- private:
- AirConditioner& airConditioner;
- public:
- AirConditionerOnCommand(AirConditioner& airConditioner) : airConditioner(airConditioner) {}
- void execute() override {
- airConditioner.on();
- }
- };
-
- // 具体命令:关闭空调
- class AirConditionerOffCommand : public Command {
- private:
- AirConditioner& airConditioner;
- public:
- AirConditionerOffCommand(AirConditioner& airConditioner) : airConditioner(airConditioner) {}
- void execute() override {
- airConditioner.off();
- }
- };
-
- // 遥控器
- class RemoteControl {
- private:
- std::vector
> onCommands; - std::vector
> offCommands; - public:
- void setCommand(size_t slot, std::shared_ptr
onCommand, std::shared_ptr offCommand) { - if (slot >= onCommands.size()) {
- onCommands.resize(slot + 1);
- offCommands.resize(slot + 1);
- }
- onCommands[slot] = onCommand;
- offCommands[slot] = offCommand;
- }
- void onButtonPressed(size_t slot) {
- if (slot < onCommands.size() && onCommands[slot]) {
- onCommands[slot]->execute();
- }
- }
- void offButtonPressed(size_t slot) {
- if (slot < offCommands.size() && offCommands[slot]) {
- offCommands[slot]->execute();
- }
- }
- };
-
- int main() {
- Light livingRoomLight;
- TV livingRoomTV;
- AirConditioner livingRoomAC;
-
- auto livingRoomLightOn = std::make_shared
(livingRoomLight); - auto livingRoomLightOff = std::make_shared
(livingRoomLight); - auto livingRoomTVOn = std::make_shared
(livingRoomTV); - auto livingRoomTVOff = std::make_shared
(livingRoomTV); - auto livingRoomACOn = std::make_shared
(livingRoomAC); - auto livingRoomACOff = std::make_shared
(livingRoomAC); -
- RemoteControl remote;
- remote.setCommand(0, livingRoomLightOn, livingRoomLightOff);
- remote.setCommand(1, livingRoomTVOn, livingRoomTVOff);
- remote.setCommand(2, livingRoomACOn, livingRoomACOff);
-
- remote.onButtonPressed(0);
- remote.offButtonPressed(0);
- remote.onButtonPressed(1);
- remote.offButtonPressed(1);
- remote.onButtonPressed(2);
- remote.offButtonPressed(2);
-
- return 0;
- }
用命令模式来执行一系列文件操作(如创建、删除、重命名文件)。
- #include
- #include
- #include
- #include
-
- // 命令接口
- class Command {
- public:
- virtual ~Command() = default;
- virtual void execute() = 0;
- virtual void undo() = 0;
- };
-
- // 接收者:文件系统
- class FileSystem {
- public:
- void createFile(const std::string& filename) {
- std::cout << "File created: " << filename << "\n";
- }
- void deleteFile(const std::string& filename) {
- std::cout << "File deleted: " << filename << "\n";
- }
- void renameFile(const std::string& oldName, const std::string& newName) {
- std::cout << "File renamed from " << oldName << " to " << newName << "\n";
- }
- };
-
- // 具体命令:创建文件
- class CreateFileCommand : public Command {
- private:
- FileSystem& fileSystem;
- std::string filename;
- public:
- CreateFileCommand(FileSystem& fs, const std::string& filename) : fileSystem(fs), filename(filename) {}
- void execute() override {
- fileSystem.createFile(filename);
- }
- void undo() override {
- fileSystem.deleteFile(filename);
- }
- };
-
- // 具体命令:删除文件
- class DeleteFileCommand : public Command {
- private:
- FileSystem& fileSystem;
- std::string filename;
- public:
- DeleteFileCommand(FileSystem& fs, const std::string& filename) : fileSystem(fs), filename(filename) {}
- void execute() override {
- fileSystem.deleteFile(filename);
- }
- void undo() override {
- fileSystem.createFile(filename);
- }
- };
-
- // 具体命令:重命名文件
- class RenameFileCommand : public Command {
- private:
- FileSystem& fileSystem;
- std::string oldName;
- std::string newName;
- public:
- RenameFileCommand(FileSystem& fs, const std::string& oldName, const std::string& newName)
- : fileSystem(fs), oldName(oldName), newName(newName) {}
- void execute() override {
- fileSystem.renameFile(oldName, newName);
- }
- void undo() override {
- fileSystem.renameFile(newName, oldName);
- }
- };
-
- // 命令管理器
- class CommandManager {
- private:
- std::stack
> commandStack; - std::stack
> redoStack; - public:
- void executeCommand(std::shared_ptr
command) { - command->execute();
- commandStack.push(command);
- while (!redoStack.empty()) {
- redoStack.pop();
- }
- }
- void undo() {
- if (!commandStack.empty()) {
- auto command = commandStack.top();
- commandStack.pop();
- command->undo();
- redoStack.push(command);
- }
- }
- void redo() {
- if (!redoStack.empty()) {
- auto command = redoStack.top();
- redoStack.pop();
- command->execute();
- commandStack.push(command);
- }
- }
- };
-
- int main() {
- FileSystem fileSystem;
-
- auto createFile = std::make_shared
(fileSystem, "example.txt"); - auto deleteFile = std::make_shared
(fileSystem, "example.txt"); - auto renameFile = std::make_shared
(fileSystem, "example.txt", "example1.txt"); -
- CommandManager commandManager;
- commandManager.executeCommand(createFile);
- commandManager.executeCommand(renameFile);
- commandManager.undo();
- commandManager.redo();
- commandManager.executeCommand(deleteFile);
- commandManager.undo();
-
- return 0;
- }
命令模式在开发中可以帮助我们将请求封装为对象,并提供对请求执行、撤销和重做的支持。