C++中的命令模式

目录

命令模式(Command Pattern)

实际应用

家庭自动化系统

文件操作系统

总结


命令模式(Command Pattern)

命令模式是一种行为型设计模式,它将一个请求封装成一个对象,从而使您可以用不同的请求对客户端进行参数化、对请求排队或记录请求日志,以及支持可撤销的操作。命令模式将请求的发出者和执行者解耦,使得请求的发送者无需知道执行请求的具体操作。

实际应用

家庭自动化系统

命令模式来实现控制各种设备(如灯、电视、空调)。

#include <iostream>
#include <memory>
#include <vector>

// 命令接口
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<std::shared_ptr<Command>> onCommands;
    std::vector<std::shared_ptr<Command>> offCommands;
public:
    void setCommand(size_t slot, std::shared_ptr<Command> onCommand, std::shared_ptr<Command> 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<LightOnCommand>(livingRoomLight);
    auto livingRoomLightOff = std::make_shared<LightOffCommand>(livingRoomLight);
    auto livingRoomTVOn = std::make_shared<TVOnCommand>(livingRoomTV);
    auto livingRoomTVOff = std::make_shared<TVOffCommand>(livingRoomTV);
    auto livingRoomACOn = std::make_shared<AirConditionerOnCommand>(livingRoomAC);
    auto livingRoomACOff = std::make_shared<AirConditionerOffCommand>(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 <iostream>
#include <stack>
#include <memory>
#include <string>

// 命令接口
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<std::shared_ptr<Command>> commandStack;
    std::stack<std::shared_ptr<Command>> redoStack;
public:
    void executeCommand(std::shared_ptr<Command> 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<CreateFileCommand>(fileSystem, "example.txt");
    auto deleteFile = std::make_shared<DeleteFileCommand>(fileSystem, "example.txt");
    auto renameFile = std::make_shared<RenameFileCommand>(fileSystem, "example.txt", "example1.txt");

    CommandManager commandManager;
    commandManager.executeCommand(createFile);
    commandManager.executeCommand(renameFile);
    commandManager.undo();
    commandManager.redo();
    commandManager.executeCommand(deleteFile);
    commandManager.undo();

    return 0;
}

总结

命令模式在开发中可以帮助我们将请求封装为对象,并提供对请求执行、撤销和重做的支持。

相关推荐

  1. C++命令模式

    2024-06-11 18:44:05       24 阅读
  2. 设计模式:生活命令模式

    2024-06-11 18:44:05       38 阅读
  3. C++模板方法模式

    2024-06-11 18:44:05       25 阅读
  4. C++外观模式

    2024-06-11 18:44:05       29 阅读
  5. C++适配器模式

    2024-06-11 18:44:05       30 阅读
  6. C++原型模式

    2024-06-11 18:44:05       26 阅读
  7. C++组合模式

    2024-06-11 18:44:05       26 阅读
  8. C++状态模式

    2024-06-11 18:44:05       29 阅读
  9. C++策略模式

    2024-06-11 18:44:05       29 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-11 18:44:05       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-11 18:44:05       106 阅读
  3. 在Django里面运行非项目文件

    2024-06-11 18:44:05       87 阅读
  4. Python语言-面向对象

    2024-06-11 18:44:05       96 阅读

热门阅读

  1. 结构化表达,了解python的pep

    2024-06-11 18:44:05       32 阅读
  2. 关系模式R(U,F)【数据库-软件设计师】

    2024-06-11 18:44:05       28 阅读
  3. 常用的三种软件架构

    2024-06-11 18:44:05       30 阅读
  4. GMT shp转gmt数据

    2024-06-11 18:44:05       28 阅读
  5. 数据库文件的简单设计

    2024-06-11 18:44:05       23 阅读
  6. 关于AD9781芯片的说明以及FPGA控制实现 I

    2024-06-11 18:44:05       30 阅读
  7. Web前端后端精通:深度解析与技能进阶

    2024-06-11 18:44:05       29 阅读
  8. Ascend ATC相关参数说明和描述

    2024-06-11 18:44:05       30 阅读
  9. Android:UI:Drawable:View/ImageView与Drawable

    2024-06-11 18:44:05       27 阅读
  10. 【Linux】另一种基于rpm安装yum的方式

    2024-06-11 18:44:05       34 阅读
  11. 一五一、Go入门到进阶:并发编程

    2024-06-11 18:44:05       21 阅读
  12. PHP运算符:从基础到高级

    2024-06-11 18:44:05       27 阅读