当前位置: 首页 > article >正文

命令模式(C++)三分钟读懂

命令模式(Command Pattern)是一种行为设计模式,它将请求封装成一个对象,从而使得可以参数化客户端对象传递不同的请求,并且能够支持请求的排队、记录请求日志、撤销操作等。在命令模式中,请求发送者和请求接收者之间通过命令对象进行解耦,从而实现了请求发送者和请求接收者之间的松耦合。

下面是一个使用QT C++编写的简单命令模式示例,

代码演示:

#include <QCoreApplication>
#include <QDebug>
#include <QString>

// 命令接口 作为一个基类
class Command {
public:
    virtual ~Command() {}
    virtual void execute() = 0;    // 执行
    virtual void undo() = 0;        // 撤销    
};

// 具体命令类 继承命令接口类
class LightOnCommand : public Command {
public:
    void execute() override {
        qDebug() << "开灯";
    }
    void undo() override {
        qDebug() << "撤销开灯";
    }
};

class LightOffCommand : public Command {
public:
    void execute() override {
        qDebug() << "关灯";
    }
    void undo() override {
        qDebug() << "撤销关灯";
    }
};

// 命令调用者
class RemoteControl {
public:
    // 可以接收命令基类对象指针
    void setCommand(Command* command) {
        m_command = command;
    }

   void pressButton() {
        if (m_command) {
            m_command->execute();
            m_undoStack.push(m_command);    // 将对象入栈
        } else {
            qDebug() << "无命令写入";
        }
    }

    void undoButton() {
        if (!m_undoStack.empty()) {
            Command* lastCommand = m_undoStack.top();    // 取出栈顶部对象(最后一个加入容器的对象)
            lastCommand->undo();
            m_undoStack.pop();    // 删除顶部对象
        } else {
            qDebug() << "无撤销操作";
        }
    }

private:
    Command* m_command;    // 保存命令对象指针
    std::stack<Command*> m_undoStack;    // 栈容器,用于保存使用过命令的对象
};

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    // 创建命令调用者对象
    RemoteControl remote;

    // 创建两个不同的命令对象
    LightOnCommand lightOnCmd;
    LightOffCommand lightOffCmd;

    // 将不同的命令对象传入 调用者对象 ,然后执行命令
    remote.setCommand(&lightOnCmd);
    remote.pressButton();

    remote.setCommand(&lightOffCmd);
    remote.pressButton();

    remote.undoButton();

    return a.exec();
}

优点:

  1. 松耦合:命令模式将请求发送者和请求接收者解耦,使得请求发送者无需知道请求接收者的具体实现,从而降低系统的耦合度。

  2. 可扩展性:通过添加新的命令类,可以轻松地扩展系统的功能,而无需修改现有的代码。

  3. 支持撤销和重做:由于命令对象封装了请求,可以轻松地实现请求的撤销和重做操作。

  4. 支持日志记录:可以通过保存命令对象的历史记录,实现日志记录功能,便于跟踪和调试。

缺点:

  1. 类爆炸:如果系统中有大量的命令类,可能会导致类的数量急剧增加,增加系统的复杂性。

  2. 增加代码量:引入命令模式会增加额外的类和对象,可能会增加代码量,使得代码变得更加复杂。

  3. 可能降低性能:由于命令模式需要创建额外的对象来封装请求,可能会导致一定程度上的性能损失。

总的来说,命令模式在需要将请求发送者和请求接收者解耦、支持撤销和重做、支持日志记录等场景下非常有用。在实际应用中,需要根据具体的需求和场景权衡其优缺点,选择合适的设计模式。


http://www.kler.cn/a/370636.html

相关文章:

  • 如何在服务器同一个端口下根据路径区分不同的应用
  • LDD3学习7--硬件接口I/O端口(以short为例)
  • RPA赋能内容创作:打造小红书入门词语图片的全自动化流程
  • 构建一个简单的深度学习模型
  • 大模型WebUI:Gradio全解11——Chatbot:融合大模型的多模态聊天机器人(6)
  • 28:CAN总线入门一:CAN的基本介绍
  • 企业如何用WordPress站群布局多个行业站点,轻松覆盖关键词
  • Linux之nfs服务器和dns服务器
  • node升级package.json中的版本
  • pip 和 pipx 的主要区别?
  • Vue笔记-element ui中关于table的前端分页
  • CSS 样式 box-sizing: border-box; 用于控制元素的盒模型如何计算宽度和高度
  • 解决minio跨域问题
  • 【数据结构和算法】三、动态规划原理讲解与实战演练
  • IDEA2023
  • 题目欣赏 之 初心数
  • 【PythonWeb开发】Flask-RESTful参数解析
  • HTTPS 协议原理
  • JS+Springboot做一个交互Demo
  • css 3D效果实现六面体(易)
  • 【优选算法篇】前缀之序,后缀之章:于数列深处邂逅算法的光与影
  • Docker搭建基于Nextcloud的个人云盘/私有云盘/个人相册/家庭NAS
  • Git_IDEA集成GitHub
  • 基于springboot+vue实现的快递物流信息查询系统 (源码+L文+ppt)4-099
  • LeetCode:459重复的子字符串
  • 数据结构 - 图