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

C++ 设计模式《订单的撤销和重做》

👨‍🎓 模式名称:命令模式(Command)

👦 故事背景:

小明的“万能校园生活平台”新增了一键下单功能,每个订单会自动派送给骑手去完成。
但是用户开始频繁出现这类操作:

  • ❌ 下完订单又想撤销
  • 🔁 撤销后又反悔,想恢复订单
  • 🧾 打印操作日志或恢复崩溃数据

这下糟了!如果没有一个“命令历史”机制,撤销和重做就成了噩梦。
于是小明决定:

我要用【命令模式】来搞定撤销与重做系统!

✅ 使用命令模式的设计

🔧 1. 定义命令接口
class Command {
public:virtual void execute() = 0;virtual void undo() = 0;virtual ~Command() {}
};
2. 接收者类(骑手)
class Rider {
public:void deliver(const std::string& order) {std::cout << "🚴‍♂️ 派送订单:" << order << std::endl;}void cancel(const std::string& order) {std::cout << "❌ 撤销订单:" << order << std::endl;}
};
3. 具体命令类(一个订单 = 一个命令对象)
class DeliverCommand : public Command {
public:DeliverCommand(Rider* r, const std::string& o) : rider(r), order(o) {}void execute() override {rider->deliver(order);}void undo() override {rider->cancel(order);}private:Rider* rider;std::string order;
};
4. 调度器(Invoker):支持撤销和重做
#include <stack>class CommandManager {
public:void executeCommand(Command* cmd) {cmd->execute();undoStack.push(cmd);// 清空 redo 栈while (!redoStack.empty()) redoStack.pop();}void undo() {if (!undoStack.empty()) {Command* cmd = undoStack.top();undoStack.pop();cmd->undo();redoStack.push(cmd);}}void redo() {if (!redoStack.empty()) {Command* cmd = redoStack.top();redoStack.pop();cmd->execute();undoStack.push(cmd);}}private:std::stack<Command*> undoStack;std::stack<Command*> redoStack;
};
🚀 示例使用
int main() {Rider rider;CommandManager manager;Command* order101 = new DeliverCommand(&rider, "奶茶订单#101");Command* order102 = new DeliverCommand(&rider, "烧烤订单#102");manager.executeCommand(order101);  // 派送奶茶manager.executeCommand(order102);  // 派送烧烤std::cout << "🚫 用户撤销一个订单:" << std::endl;manager.undo(); // 撤销烧烤订单std::cout << "↩️ 用户反悔,重做一个订单:" << std::endl;manager.redo(); // 重做烧烤订单// 清理delete order101;delete order102;
}

❌ 不使用命令模式时(撤销逻辑耦合)

#include <vector>
#include <string>class Rider {
public:void deliver(const std::string& order) {std::cout << "🚴 派送:" << order << std::endl;history.push_back(order);}void cancelLast() {if (!history.empty()) {std::cout << "❌ 撤销:" << history.back() << std::endl;history.pop_back();}}private:std::vector<std::string> history;
};int main() {Rider rider;rider.deliver("奶茶订单#101");rider.deliver("烧烤订单#102");rider.cancelLast(); // 只能撤销最后一单
}

🧨 问题:

  • 撤销逻辑和执行逻辑耦合在 Rider 里
  • 无法“重做”
  • 扩展操作记录、日志、存储等困难

✅ 总结:命令模式的优势

场景命令模式传统写法
撤销操作✅ 支持❌ 手动处理
重做操作✅ 支持
日志记录✅ 可序列化命令对象❌ 不可持久化
解耦调用者/执行者✅ 调用者不关心执行细节❌ 代码耦合
http://www.dtcms.com/a/581934.html

相关文章:

  • 国网法治建设网站阿里巴巴推广平台
  • 【AI学习-comfyUI学习-SDXL 风格化提示词节点包(Style Prompt Node Pack) 工作流-各个部分学习-第四节】
  • 怎样建设有价值的网站天津建设工程信息网中标公告
  • 提升大语言模型性能的关键技术清单(from 网络)
  • 【NLP】Penn Treebank 与 Parsing:让计算机看懂句子结构
  • Go 1.25 发布:性能、工具与生态的全面进化
  • 北京市保障性住房建设投资中心网站淮南吧
  • Duilib_CEF桌面软件实战之Duilib编译与第一个界面程序
  • MFC动态加载图片
  • Niagara Launcher 全新Android桌面启动器!给手机换个门面!
  • 【Vue】自定义指令之权限控制
  • asp.net网站第一次运行慢网站建设合同书保密条款
  • ZYNQ-7000双核协处理实战:ARM Cortex-A9与FPGA的智能数据采集系统
  • 慈溪哪里有做网站怎么看网站pv
  • 【PySpark】conda create -n pyspark python=3.8报错
  • CSS 数学函数完全指南:从基础计算到高级动画
  • uni-app打包app -- 在用户首次启动 App 时,强制弹出一个“用户协议与隐私政策”的确认对话框。
  • 互联网网站排名深圳住房和城乡建设局网站
  • Wi-Fi 7通信技术
  • @InitBinder注解
  • 20251107给荣品RD-RK3588-MID开发板跑Rockchip的原厂Android13系统时适配8寸屏的CTP【使用荣品的DTS】
  • 《隐匿之智:AI暗潮下的末日序章》
  • 网站建设玖金手指谷哥四wordpress注册怎样通过邮箱验证码
  • 山东首台(套)高端装备申报材料及申报流程解读
  • “互联网之光” 博览会启幕,AI+生活场景让科技触手可及
  • 应对 “读放大” 问题的新方法 —— OceanBase 中的 Merge-On-Write 表
  • 48_AI智能体核心业务之钉钉服务集成全局主控Agent:构建企业级智能助手的工程实践
  • 网站如何实现临时聊天wordpress 多店铺
  • 郑州做网站 哪家好wordpress 获取文章数量
  • 友汇网网站建设自考网页制作与网站建设