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

命令模式(Command Pattern)★

命令模式(Command Pattern)
如果任务有多个复杂的操作,可以使用命令模式将任务的操作封装为命令对象。这些命令对象可以在需要时按顺序执行,方便管理任务执行的逻辑和回滚操作。

示例:
class Command {
public:
    virtual void execute() = 0;  // 执行命令
};

class RunTaskCommand : public Command {
private:
    Task *task;

public:
    RunTaskCommand(Task *task) : task(task) {}

    void execute() override {
        task->runTask();
    }
};






命令模式(Command Pattern)是一种行为设计模式,它将请求封装为一个对象,从而使用户可用不同的请求对客户进行参数化。它还可以将请求排队、记录请求日志,以及支持可撤销的操作。以下是对命令模式的详细解释,以及如何理解它的用途。

命令模式的核心概念

  1. Command(命令接口)

    • 定义了一个执行操作的接口,通常包含一个 execute() 方法。
    • 所有具体命令类都实现这个接口。
  2. ConcreteCommand(具体命令类)

    • 实现了 Command 接口,具体执行某个操作。
    • 通常包含一个对 Receiver(接收者)的引用,调用 Receiver 的方法来完成实际操作。
  3. Receiver(接收者)

    • 实际执行操作的对象。
    • 具体命令类会调用 Receiver 的方法来完成实际操作。
  4. Invoker(调用者)

    • 要求命令执行这个请求的对象。
    • 它调用命令对象的 execute() 方法,但并不知道具体的命令逻辑。
  5. Client(客户端)

    • 创建具体命令对象,并将具体命令对象和接收者对象组装在一起。
    • 客户端将命令对象传递给调用者对象。

示例代码解析

以下是一个完整的命令模式示例,包括命令接口、具体命令类、接收者类和调用者类。

1. 命令接口(Command)
class Command {
public:
    virtual ~Command() {}
    virtual void execute() = 0;  // 执行命令
};
2. 接收者类(Receiver)
class Task {
public:
    virtual ~Task() {}
    virtual void runTask() = 0;  // 实际执行的任务
};
3. 具体任务类(Concrete Receiver)
class MetricTask : public Task {
public:
    void runTask() override {
        std::cout << "Executing Metric Task" << std::endl;
    }
};

class MillimeterTask : public Task {
public:
    void runTask() override {
        std::cout << "Executing Millimeter Task" << std::endl;
    }
};
4. 具体命令类(Concrete Command)
class RunTaskCommand : public Command {
private:
    Task* task;

public:
    RunTaskCommand(Task* task) : task(task) {}

    void execute() override {
        task->runTask();
    }
};
5. 调用者类(Invoker)
class TaskInvoker {
private:
    Command* command;

public:
    void setCommand(Command* cmd) {
        command = cmd;
    }

    void executeCommand() {
        if (command) {
            command->execute();
        }
    }
};

使用示例

以下是如何使用命令模式来执行任务的示例:

#include <iostream>

int main() {
    // 创建具体的任务对象
    MetricTask metricTask;
    MillimeterTask millimeterTask;

    // 创建具体的命令对象,并将任务对象传递给命令对象
    RunTaskCommand metricCommand(&metricTask);
    RunTaskCommand millimeterCommand(&millimeterTask);

    // 创建调用者对象,并将命令对象传递给调用者
    TaskInvoker invoker;
    invoker.setCommand(&metricCommand);
    invoker.executeCommand();  // 输出: Executing Metric Task

    invoker.setCommand(&millimeterCommand);
    invoker.executeCommand();  // 输出: Executing Millimeter Task

    return 0;
}

输出

Executing Metric Task
Executing Millimeter Task

命令模式的用途

  1. 解耦客户端和接收者

    • 客户端(调用者)不需要直接调用接收者的方法,而是通过命令对象间接调用。这使得客户端和接收者之间解耦,客户端不需要知道具体的实现细节。
  2. 支持撤销和重做操作

    • 命令模式可以扩展为支持撤销和重做操作。通过在命令对象中保存操作前的状态,可以在需要时撤销操作。
  3. 支持命令队列和日志记录

    • 命令对象可以被存储在队列中,按顺序执行。同时,命令对象可以记录执行的操作,便于日志记录和审计。
  4. 支持宏命令

    • 可以将多个命令组合成一个宏命令,通过一个命令对象来执行多个操作。

总结

命令模式的核心在于将请求封装为一个对象,从而实现解耦和扩展性。通过命令模式,客户端可以不知道具体的实现细节,同时支持撤销、重做、命令队列和日志记录等功能。希望这个解释和示例能帮助你更好地理解命令模式的用途和实现方式。

相关文章:

  • Linux内核调试 - Hung_task机制分析上
  • 语言模型理论基础-持续更新-思路清晰
  • 无人机螺旋桨平衡标准
  • LangChain开发(二)LangChain提示词模板Template使用
  • 2.7 进度控制习题-2
  • 【JS】反转字符串中的单词
  • 计算机网络基础:WiFi 与蓝牙的原理与应用
  • JavaScript中的继承有哪些方式?各有什么优缺点
  • 强化学习与神经网络结合(以 DQN 展开)
  • STL之空间配置器
  • 【深度学习与实战】2.1、线性回归模型与梯度下降法先导
  • 数据结构:利用递推式计算next表
  • PostgreSQL详解
  • SiLU与GeLU激活函数:现代大模型的选择
  • WindowsPowerShell、CMD Linux Bash对比分析
  • 工作中遇到的spark SQL小问题:包含某个或某些字符的条件
  • uniapp + Axios + 小程序封装网络请求
  • 力扣HOT100之子串:76. 最小覆盖子串
  • mock.js模拟数据
  • 在linux部署网站
  • 中演协:五一假期全国营业性演出票房收入同比增长3.6%
  • 牛市早报|“五一”假期预计跨区域人员流动量累计14.67亿人次
  • 上海畅通“外转内”,外贸优品成“香饽饽”
  • 各地各部门贯彻落实习近平总书记重要指示精神坚决防范遏制重特大事故发生
  • 岳伟华任北京大学第六医院院长,陆林院士卸任
  • 张家口一景区观光魔毯疑失控致游客被甩出,涉事景区改造升级重新开园才3天