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

从C++编程入手设计模式——命令模式

从C++编程入手设计模式——命令模式

​ 命令模式是一个用指令封装请求的优雅方法。换而言之,对于一个复杂的系统,当我们发现,使用一系列的指令(Command)来操作对象的时候,这个设计模式就会显得非常的实用。我们经常遇到这样的场景:用户点击一个按钮,希望执行某个操作,比如保存文件、删除一条记录、或撤销上一步操作。我们通常会写一段代码来直接响应这个按钮事件。然而,如果我们希望这个操作是可以记录、撤销、重做,甚至延迟执行的,传统的方式就变得笨拙而混乱。

​ 这个时候,命令模式(Command Pattern)就派上用场了。它的核心思想很简单:把每一个操作封装成一个对象。这样,我们就可以把操作当作数据一样存储、传递、撤销甚至组合。命令模式中通常有几个角色:命令对象(Command)、接收者(Receiver)、调用者(Invoker)和客户端。命令对象负责封装“做什么”;接收者是实际干活的人;调用者是触发命令的人;客户端负责把它们组合在一起。

​ 我们可以想象一个遥控器控制家电的例子。电灯是接收者,它有开和关的功能;开灯命令和关灯命令是命令对象;遥控器就是调用者,它保存着按钮和命令的映射;用户就是客户端,负责把命令装进遥控器并按下按钮。

#include <iostream>
#include <memory>
#include <vector>// 命令接口
class Command {
public:virtual void execute() = 0;virtual ~Command() = default;
};// 接收者
class Receiver {
public:void action() {std::cout << "Receiver: Executing action.\n";}
};// 具体命令
class ConcreteCommand : public Command {
private:std::shared_ptr<Receiver> receiver;
public:explicit ConcreteCommand(std::shared_ptr<Receiver> r) : receiver(std::move(r)) {}void execute() override {receiver->action();}
};// 调用者
class Invoker {
private:std::vector<std::shared_ptr<Command>> commandQueue;
public:void addCommand(std::shared_ptr<Command> cmd) {commandQueue.push_back(std::move(cmd));}void run() {for (const auto& cmd : commandQueue) {cmd->execute();}commandQueue.clear();}
};int main() {auto receiver = std::make_shared<Receiver>();auto command = std::make_shared<ConcreteCommand>(receiver);Invoker invoker;invoker.addCommand(command);invoker.run();return 0;
}

​ 如你所见,这个就是常见的命令模式的模板代码。

优缺点讨论

命令模式的一个好处是,它实现了调用者和接收者之间的彻底解耦。调用者并不知道命令怎么执行,它只知道有个命令对象可以被触发。这使得我们可以在不改变调用者的前提下,轻松替换命令,甚至在运行时动态改变行为。

此外,命令模式还为我们带来了其他附加功能。比如,可以将命令记录到列表中,支持撤销和重做;可以组合多个命令形成宏命令,实现批量操作;可以把命令序列化之后发到远程服务器执行,实现远程控制。

不过命令模式也有它的代价。每个操作都要定义一个命令类,当操作很多时,类的数量会迅速增加。此外,为了支持撤销,命令对象还需要记录足够的信息,这可能会带来额外的内存负担。

练习题:通过命令控制文本编辑器

描述
模拟一个文本编辑器,用户可以执行“添加文字”、“删除文字”等操作,每个操作为一个命令。

要求

  • 接收者 TextDocument,支持添加和删除字符
  • 命令:AddTextCommand, DeleteTextCommand
  • 支持撤销操作
  • Invoker 为 EditorInvoker,负责管理执行历史

modern-cpp-patterns-playground/Command/TextEditor at main · Charliechen114514/modern-cpp-patterns-playground

相关文章:

  • LeapMotion-PhysicalHandsManager 类详解
  • 关于控制结构知识点的详细讲解(从属GESP一级内容)
  • 在 Windows 和 Linux 下使用 C/C++ 连接 MySQL 的详细指南
  • 通义大模型与现有企业系统集成实战《CRM案例分析与安全最佳实践》
  • 《jQuery CSS 类的使用与优化》
  • CSS平滑滚动效果实现方法
  • uni-app项目实战笔记23--解决首次加载额外图片带来的网络消耗问题
  • Spark教程6:Spark 底层执行原理详解
  • 合成生物学与人工智能的融合:从生命编程到智能设计的IT新前沿
  • 前端手写题(一)
  • 计算机网络通信技术与协议(九)————交换机技术
  • 量化面试绿皮书:33. 不公平的硬币
  • 拯救海量数据:PostgreSQL分区表性能优化实战手册(附压测对比)
  • 发送与接收
  • 写一下自己对于“李建忠对话KK凯文.凯利《AI的进化和颠覆》实录”一些问题的理解
  • 群晖如何开启及使用ssh:小白用户上手指南-家庭云计算专家
  • Rabbitmq集成springboot 使用死信队列
  • [计算机网络] 局域网内的网络传输
  • 【Android】初识 Activity
  • 【人工智能基础】初识神经网络
  • wordpress发微信公众号/菏泽地网站seo
  • 做一个网站需要什么条件/昆明seo关键词排名
  • wordpress插件安装本地安装教程/众志seo
  • 长沙做网站的故事/网络营销策划与推广
  • wordpress阿里秀模板/搜狗排名优化工具
  • 网上做预算有哪些网站/加盟教育培训哪个好