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

发布于:2024-11-02 ⋅ 阅读:(10) ⋅ 点赞:(0)

命令模式(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. 可能降低性能:由于命令模式需要创建额外的对象来封装请求,可能会导致一定程度上的性能损失。

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