C++ 命令模式怎么实现?命令模式在C++中的用法详解

文章导读
Previous Quiz Next Command Design Pattern(命令设计模式)是一种将请求——比如让灯亮起——转化为独立对象的方法。这意味着你可以将动作当作可传递、可保存以备后用,甚至可以撤销的对象来处理。
📋 目录
  1. 命令设计模式的组件
  2. C++ 中命令设计模式的实现
  3. 在 C++ 中实现命令设计模式的步骤
  4. C++ 命令设计模式代码示例
  5. 命令设计模式的优缺点
  6. 命令设计模式的实际应用场景
  7. 总结
A A

C++ 中的命令设计模式



Previous
Quiz
Next

Command Design Pattern(命令设计模式)是一种将请求——比如让灯亮起——转化为独立对象的方法。这意味着你可以将动作当作可传递、可保存以备后用,甚至可以撤销的对象来处理。

简单来说,它允许你将一个动作及其所需的所有细节封装起来,以便随时执行。这使得你的代码更加灵活且易于管理,尤其是在需要添加撤销功能或记录历史时。

例如,在文本编辑器中,Copy(复制)、Paste(粘贴)和Undo(撤销)等动作都可以成为独立的命令对象。这使得执行它们、排队或在改变主意时撤销它们变得非常容易。

在下面的图片中,你可以看到遥控器向灯源发送命令。遥控器(Invoker)不知道灯(Receiver)是如何工作的;它只是使用Command对象告诉灯开启或关闭。

Command Design Pattern

命令设计模式的组件

以下是Command Design Pattern的主要组件:

  • Command − 这只是一个接口或抽象类,包含类似execute()的方法。它定义了“命令应该是什么样子”的通用方式。
  • ConcreteCommand − 这些是实际的命令类。每个类执行特定操作,比如开启或关闭灯。它们知道要操作哪个对象以及执行什么动作。
  • Client − 这是将一切组合起来的代码部分。它创建命令对象并告诉它们应该控制哪些对象。
  • Invoker − 可以将其想象成遥控器。它不知道命令做什么,只知道如何请求命令执行其工作。
  • Receiver − 这是真正执行工作的对象。当命令被执行时,它实际完成工作,比如开启或关闭的灯。

C++ 中命令设计模式的实现

在本例中,我们将实现一个简单的命令模式示例,其中有一个light,可以使用命令对象将其开启和off

在 C++ 中实现命令设计模式的步骤

以下是在 C++ 中实现Command Design Pattern的步骤

Steps to Implement Command Design Pattern
  • 首先,为你的命令创建一个interface(或抽象类),包含类似execute()的方法。
  • 接下来,为每个command(比如开启或关闭灯)创建实现该接口的类。
  • 然后,为你要控制的对象创建一个类(例如,Light类,知道如何开启或关闭自身)。
  • 之后,创建一个“invoker”类(类似于遥控器),它将使用命令对象来执行工作。
  • 最后,在主代码中,将一切组合起来:创建命令,将它们连接到要控制的对象,并使用 invoker 来运行它们。

C++ 命令设计模式代码示例

以下是一个简单的 C++ 代码示例,演示了 Command Design Pattern −

#include <iostream>
using namespace std;

// Command 接口
class Command {
public:
   virtual void execute() = 0;
};

// Receiver 类
class Light {
public:
   void on() {
       cout << "Light is ON" << endl;
   }
   void off() {
       cout << "Light is OFF" << endl;
   }
};

// 打开灯的具体命令
class LightOnCommand : public Command {
private:
   Light* light;
public:
   LightOnCommand(Light* l) : light(l) {}
    void execute() override {
         light->on();
    }
};

// 关闭灯的具体命令
class LightOffCommand : public Command {
private:
   Light* light;
public:
   LightOffCommand(Light* l) : light(l) {}
    void execute() override {
         light->off();
    }
};

// Invoker 类
class RemoteControl {
private:
   Command* command;
public:
   void setCommand(Command* cmd) {
      command = cmd;
   }

   void pressButton() {
      command->execute();
   }

};

// 客户端代码
int main() {
   Light* light = new Light();

   Command* lightOn = new LightOnCommand(light);
   Command* lightOff = new LightOffCommand(light);

   RemoteControl* remote = new RemoteControl();

   // 打开灯
   remote->setCommand(lightOn);
   remote->pressButton();

   // 关闭灯
   remote->setCommand(lightOff);
   remote->pressButton();

   // 清理资源
   delete light;
   delete lightOn;
   delete lightOff;
   delete remote;

   return 0;
}

以上代码的输出结果如下 −

Light is ON
Light is OFF

在这个示例中,我们定义了一个带有 execute 方法的 Command 接口。Light 类充当 Receiver,知道如何打开和关闭灯。LightOnCommand 和 LightOffCommand 类是实现 Command 接口的 ConcreteCommand 类。RemoteControl 类是 Invoker,调用命令来执行请求。最后,在 main 函数中,我们创建命令的实例,并使用 RemoteControl 来执行它们。

命令设计模式的优缺点

优点 缺点
便于将发送请求的对象与实际执行工作的对象分离 可能会产生大量的command 类
可以添加撤销重做功能 使代码变得有些复杂
可以队列化或记录日志请求以供后续使用 需要额外的来工作
允许将不同的请求分配给同一个客户端 对于简单任务来说可能过于繁琐
保持代码整洁,更容易管理 可能会使查找bug变得更困难
增强了执行命令的灵活性 可能存在性能开销

命令设计模式的实际应用场景

  • 在图形用户界面中,处理如点击按钮或选择菜单项等操作。
  • 文本编辑器绘图工具等程序中添加撤销重做功能。
  • 创建调度任务以后执行的系统,如job queues
  • 使用遥控器app控制智能家居设备
  • 在软件中记录并回放一系列操作作为
Real World Application of Command Design Pattern

总结

在本章中,我们学习了什么是命令设计模式、它的组成部分,以及如何在 C++ 中实现它。我们还讨论了使用此模式的优缺点以及实际应用场景。Command Design Pattern 是一种强大的工具,用于解耦请求的发送者和接收者,它支持撤销/重做等功能,并改善了代码组织。