尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

深入解析:精读C++20设计模式——行为型设计模式:命令模式

深入解析:精读C++20设计模式——行为型设计模式:命令模式
📅 发布时间:2026/6/20 5:44:01

精读C++20设计模式——行为型设计模式:命令模式

前言:Lets Command!

​ Command设计模式实际上不太Command。这个比较反直觉。因为Command设计模式压根就不是直接死命令对象到底怎么做事情。而是发送命令,接收对象根据发送者发送的命令执行代码。

命令模式干什么

​ 命令模式将我们对API的操作封装成命令,命令的调用就是对对象的操作。看起来好像没什么问题,比如说:

class BankAccount {
int balance = 0;
constexpr int overdraft_limit = -500;
public:
void deposit(int amount) { balance += amount; }
void withdraw(int amount) {
if(balance - amount < overdraft_limit)
return;
blance -= amount;
}
};

​ 我们把类完成了!现在我们可以这样做了。

struct Command { virtual void call() const = 0; };
struct BankAccountCmd : Command
{
BankAccount& ba;
enum class AcceptableAction { deposit, withdraw } action;
int amount;
// BankAccountCmd init omitted
void call() const override {
switch(action){
case deposit:
// process all the deposit relative
break;
case withdraw:
// process all the withdraw relative
break;
}
};
};

​ 你看到了嘛?我们现在立马就可以无任何侵入的做比直接调用显然更多的事情了:

BankAccount ba;
BankAccountCmd bacmd {ba, AcceptableAction::deposit, 500};
bacmd.call();

​ 完事。你发现我们完全可以对Command做额外的提交约束啊等一系列的事情,完全不用动BankAccount的任何代码——只要他自己相关的接口是稳定的!

​ 我们甚至还可以滚动回来!比如说我们小小的翻新一下Command(假设我们真的笃定Command是要支持撤回的)

struct Command {
virtual void call() = 0;
virtual void undo() = 0;
};

​ 现在我们自然可以根据我们实现的逻辑的撤回操作依次的完成Command的接口,最后我们就会组合成一个非常具备代码整洁的命令链条——还是支持撤回操作的那种!

组合我们的命令:结合组合模式+命令模式

​ 一堆Command的有机组合是不是也是一个Command,或者说Command的正交组合显然还是一个Command。那么,我们就有理由编写出一个更好的组合Command

struct ComposedBankCommand : Command
{
// register commands
void call() override {
for(auto& cmd : composers)  cmd->call();
};
void undo() override {
for(auto& cmd : composers)  cmd->call();
}
private:
vector<Command*>	composers;};

​ 但好像不对?如果我们中间的一个command失败了,其他的干脆就不应该调用——当然对于并行式的Command蔟完全没问题。这个是逻辑设计的差异。解决这个的办法也很好说——Command内部维护一个是否成功的操作就好了嘛!

总结:

解决什么问题

命令模式要解决的核心问题是把“动作”从调用者中剥离出来,使动作成为可传递、可存储、可组合、可撤销的对象。当程序中出现需要延迟执行、排队执行、撤销/重做、日志回放、网络传输或组合多个操作等需求时,直接在调用处硬编码调用逻辑会导致耦合、难以扩展与难以控制。命令模式把对某个接口/对象的“操作”封装成单独的对象(Command),从而把请求者与执行者解耦,同时把操作本身作为一等公民来处理(队列、日志、回滚、组合……都可以做)。

如何解决

命令模式通过定义一个统一的命令接口(比如 call() / execute(),必要时还加上 undo() / redo())来表示“要做的事”。每个具体命令包含执行该操作所需的接收者引用和参数。调用方只负责生成或提交命令对象,不直接操作接收者;命令可以被放入队列、写入日志、传到远端、组合成宏命令或在稍后执行。为支持撤销/补偿,命令可以维护执行前的状态(或借助 Memento),或者提供一个 undo() 方法做反向操作。为了支持异步、可靠性或回放,还可以给命令增加序列化/日志化能力。


各个变种的优劣对比
变种描述优点缺点典型适用场景
基本命令(Basic Command)最简形式:命令对象封装接收者和参数,实现 execute()。实现简单,耦合低,便于扩展与测试。只适合同步、一次性调用,缺少撤销/持久化支持。简单的解耦、延迟执行需求。
可撤销命令(Undoable Command)命令实现 execute() 与 undo() 或保存 Memento 做回滚。支持撤销/重做,用户体验好(编辑器、事务界面)。需要额外保存状态或实现反向操作,设计与边界条件复杂。文本编辑、图形编辑、事务局部回退。
组合命令 / 宏命令(Composite / Macro)把多个命令组合成一个命令;支持原子或顺序执行。易于复用、批量操作、一次执行多个子操作。失败处理复杂(部分成功如何回滚);错误传播要设计清楚。批处理、事务化工作流、复合操作。

相关新闻

  • Chrome 系统信息
  • YACS2025年9月甲组
  • Docker 容器与镜像 - 实践

最新新闻

  • Presenton开源AI演示生成工具:企业级演示文稿创作的完整解决方案
  • Awesome-AI 开源仓库架构设计与技术学习路线工程化沉淀方案
  • (2026新)珠海正规防水补漏公司口碑榜TOP5权威推荐!卫生间/厨房/阳台/屋顶/天花板/地下室渗漏水检测维修攻略-靠谱漏水检测维修师傅推荐 - 安佳防水
  • 深入解析CAN总线标识符过滤:原理、配置与MSCAN实战指南
  • 终极指南:跨平台获取macOS系统镜像的完整解决方案
  • 深入解析MC68HC908AS32A SPI模块:从寄存器配置到中断与错误处理实战

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号