模式特点
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。
- 备忘录对象存储原发器对象的内部状态
- 原发器负责创建和恢复备忘录
- 管理者只负责保存备忘录,不能修改其内容
- 实现撤销/恢复功能的核心模式
类图
应用场景
- Qt 中 QUndoStack 配合 QUndoCommand 实现撤销
- 示教器运动轨迹编辑:保存历史轨迹点用于撤销
- 配置编辑器:保存配置快照支持回退
- 游戏存档系统:保存游戏状态用于恢复
- 事务管理:保存数据快照用于事务回滚
示例代码(C++)
// 备忘录 - 保存运动状态 class MotionMemento { friend class RobotArm; std::vector<double> m_joints; MotionMemento(const std::vector<double>& j) : m_joints(j) {} public: const std::vector<double>& getState() const { return m_joints; } }; // 原发器 - 机器人手臂 class RobotArm { std::vector<double> m_joints; // 6轴关节角度 public: void setJoints(const std::vector<double>& j) { m_joints = j; } void show() { std::cout << "关节: "; for (auto j : m_joints) std::cout << j << " "; std::cout << std::endl; } MotionMemento* save() { return new MotionMemento(m_joints); } void restore(MotionMemento* m) { m_joints = m->m_joints; } }; // 管理者 - 撤销栈 class UndoManager { std::vector<MotionMemento*> m_stack; public: void save(RobotArm& arm) { m_stack.push_back(arm.save()); } void undo(RobotArm& arm) { if (!m_stack.empty()) { arm.restore(m_stack.back()); m_stack.pop_back(); } } }; RobotArm arm; UndoManager undoMgr; arm.setJoints({0, 0, 0, 0, 0, 0}); undoMgr.save(arm); arm.setJoints({90, 45, 30, 0, 60, 0}); undoMgr.save(arm); arm.setJoints({180, 90, 60, 0, 90, 0}); undoMgr.undo(arm); // 恢复到 {90,45,30,0,60,0}