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

备忘录模式C++

备忘录模式(Memento Pattern)是一种行为型设计模式,它允许在不暴露对象内部状态的情况下,捕获并保存对象的内部状态,以便在将来需要时恢复该状态。这种模式实现了对象状态的快照保存与恢复,常用于撤销操作、历史记录等场景。

备忘录模式的核心角色

  1. Originator(发起人):创建一个备忘录,用于记录自身当前状态;也可使用备忘录恢复状态
  2. Memento(备忘录):存储发起人的内部状态,对发起人以外的对象隐藏状态细节
  3. Caretaker(负责人):负责保存备忘录,但不能对备忘录的内容进行操作或检查

C++实现示例

以下以"文本编辑器的撤销功能"为例实现备忘录模式,支持保存文本的历史状态并在需要时恢复:

#include <iostream>
#include <string>
#include <vector>
#include <memory>// 备忘录类:存储文本状态(对外部隐藏实现细节)
class TextMemento {
private:// 只有发起人可以访问备忘录的状态friend class TextEditor;std::string content;  // 文本内容int cursorPos;        // 光标位置// 私有构造函数,防止外部创建TextMemento(std::string cont, int pos) : content(std::move(cont)), cursorPos(pos) {}
};// 发起人:文本编辑器
class TextEditor {
private:std::string content;  // 当前文本内容int cursorPos;        // 当前光标位置public:TextEditor() : cursorPos(0) {}// 输入文本void type(const std::string& text) {content.insert(cursorPos, text);cursorPos += text.length();}// 移动光标void moveCursor(int pos) {if (pos >= 0 && pos <= static_cast<int>(content.length())) {cursorPos = pos;}}// 创建备忘录(保存当前状态)std::unique_ptr<TextMemento> save() const {return std::make_unique<TextMemento>(content, cursorPos);}// 从备忘录恢复状态void restore(const TextMemento* memento) {if (memento) {content = memento->content;cursorPos = memento->cursorPos;}}// 显示当前状态void display() const {std::cout << "文本内容: " << content << std::endl;std::cout << "光标位置: " << cursorPos << std::endl;// 显示光标位置指示std::cout << "          " << std::string(cursorPos, ' ') << "^" << std::endl;}// 获取当前内容长度(用于测试)size_t getContentLength() const {return content.length();}
};// 负责人:历史记录管理器
class HistoryManager {
private:std::vector<std::unique_ptr<TextMemento>> mementos;  // 存储备忘录int currentIndex;  // 当前状态索引public:HistoryManager() : currentIndex(-1) {}// 保存新状态void saveState(std::unique_ptr<TextMemento> memento) {// 清除当前状态之后的历史(如果有)if (currentIndex < static_cast<int>(mementos.size()) - 1) {mementos.erase(mementos.begin() + currentIndex + 1, mementos.end());}// 添加新状态mementos.push_back(std::move(memento));currentIndex = mementos.size() - 1;}// 撤销操作(恢复到上一个状态)const TextMemento* undo() {if (currentIndex > 0) {currentIndex--;return mementos[currentIndex].get();}std::cout << "已到达最早状态,无法继续撤销" << std::endl;return nullptr;}// 重做操作(恢复到下一个状态)const TextMemento* redo() {if (currentIndex < static_cast<int>(mementos.size()) - 1) {currentIndex++;return mementos[currentIndex].get();}std::cout << "已到达最新状态,无法继续重做" << std::endl;return nullptr;}// 获取历史记录数量size_t getHistoryCount() const {return mementos.size();}
};// 客户端代码
int main() {// 创建文本编辑器和历史管理器TextEditor editor;HistoryManager history;// 第一次操作std::cout << "=== 第一次输入 ===" << std::endl;editor.type("Hello, ");editor.display();history.saveState(editor.save());  // 保存状态1// 第二次操作std::cout << "\n=== 第二次输入 ===" << std::endl;editor.type("World!");editor.display();history.saveState(editor.save());  // 保存状态2// 第三次操作std::cout << "\n=== 第三次输入 ===" << std::endl;editor.moveCursor(7);  // 移动光标到逗号后editor.type("Beautiful ");editor.display();history.saveState(editor.save());  // 保存状态3// 撤销一次std::cout << "\n=== 第一次撤销 ===" << std::endl;editor.restore(history.undo());editor.display();// 再撤销一次std::cout << "\n=== 第二次撤销 ===" << std::endl;editor.restore(history.undo());editor.display();// 重做一次std::cout << "\n=== 第一次重做 ===" << std::endl;editor.restore(history.redo());editor.display();return 0;
}

代码解析

  1. 备忘录(TextMemento

    • 私有构造函数确保只有发起人(TextEditor)可以创建它
    • 通过friend关键字让发起人访问其内部状态(contentcursorPos
    • 对负责人和客户端隐藏状态细节,保证封装性
  2. 发起人(TextEditor

    • 维护文本编辑器的当前状态(内容和光标位置)
    • 提供save()方法创建备忘录,捕获当前状态
    • 提供restore()方法从备忘录恢复状态
    • 包含文本编辑的核心功能(输入、移动光标等)
  3. 负责人(HistoryManager

    • 管理备忘录的存储和检索,不直接操作备忘录内容
    • 支持撤销(undo())和重做(redo())功能
    • 维护当前状态索引,正确管理历史记录的顺序
  4. 工作流程

    • 编辑器每完成一次操作,通过save()创建备忘录并交由负责人保存
    • 需要撤销时,负责人返回上一个备忘录,编辑器用其恢复状态
    • 重做功能则恢复到撤销前的状态,实现了灵活的状态回溯

备忘录模式的优缺点

优点

  • 实现了状态的封装与恢复,发起人无需暴露内部细节
  • 客户端可以通过负责人灵活地管理历史状态(撤销/重做)
  • 负责人与发起人解耦,两者各司其职(状态管理与业务逻辑)
  • 便于保存和恢复对象的任意历史状态

缺点

  • 如果对象状态较大或频繁保存,会消耗较多内存
  • 备忘录可能包含大量状态数据,复制成本较高
  • 负责人需要管理大量备忘录,增加了系统复杂度

适用场景

  • 当需要保存和恢复对象的历史状态时(如撤销操作)
  • 当不希望暴露对象的内部状态,却需要捕获和恢复状态时
  • 当需要维护对象的历史记录,以便后续分析或回滚时

常见应用:

  • 文本编辑器的撤销/重做功能
  • 数据库事务的提交与回滚
  • 游戏中的存档与读档功能
  • 图形编辑软件的历史记录功能

备忘录模式的关键是平衡封装性和灵活性:发起人保持对状态的控制,备忘录隐藏实现细节,负责人提供便捷的状态管理接口,三者协作实现安全高效的状态快照机制。

http://www.lryc.cn/news/622377.html

相关文章:

  • 线性代数 · 直观理解矩阵 | 空间变换 / 特征值 / 特征向量
  • JavaScript递归
  • nVidia Tesla P40使用anaconda本地重编译pytorch3d成功加载ComfyUI-3D-Pack
  • 磁悬浮轴承“幽灵振动”克星:深度解析同频振动机理与精准打击策略
  • 日常反思总结
  • Layui 语法详解与全功能示例
  • GoLand深度解析:智能开发利器与cpolar内网穿透的协同革命
  • 基于Spring Boot的智能民宿预订与游玩系统设计与实现 民宿管理系统 民宿预订系统 民宿订房系统
  • Linux操作系统从入门到实战(二十二)命令行参数与环境变量
  • Lecture 10: Concurrency 3
  • 【嵌入式硬件实例】-555定时器驱动直流无刷电机
  • kubernetes(序)
  • ESP32-C3_TCP
  • Windows Server存储智能数据校验
  • Spring Boot接口签名校验设计与实现
  • 办公效率提升指南:完成重复任务自动化
  • Docker Compose 入门教程
  • 图片滤镜处理(filters)
  • lidar2imu/auto_caliban以及manual_calib安装过程
  • 线程P5 | 单例模式[线程安全版]~懒汉 + 饿汉
  • 【C#补全计划】委托
  • Vue 侦听器(watch 与 watchEffect)全解析2
  • SSH协议的GIT转换
  • pyecharts可视化图表-pie:从入门到精通(进阶篇)
  • 集成电路学习:什么是Image Segmentation图像分割
  • GPT-5 官方前瞻:它将如何重塑你的数字生活?
  • 艾伦·图灵:计算理论与人工智能的奠基人
  • Linux————网络基础
  • 二分算法(模板)
  • 数据结构与算法p4