设计模式每日硬核训练 Day 18:备忘录模式(Memento Pattern)完整讲解与实战应用

🔄 回顾 Day 17:中介者模式小结

在 Day 17 中,我们学习了中介者模式(Mediator Pattern):

  • 用一个中介者集中管理对象之间的通信。
  • 降低对象之间的耦合,适用于聊天系统、GUI 控件联动、塔台调度等。

今天进入一个非常贴近用户操作体验的设计模式——备忘录模式(Memento Pattern)

备忘录模式:在不破坏封装的前提下,保存对象的内部状态,便于后续恢复到某一状态。

它是“撤销 / 恢复”操作背后的设计思想核心。


一、备忘录模式的应用动机

在许多软件中,我们都可以看到“撤销(Undo)”、“恢复(Redo)”等功能:

  • 文本编辑器可以撤销几次输入
  • 游戏中可以回到某个存档
  • 图像处理工具支持操作历史回退

这就要求:

  • 程序能保存某个时刻的状态
  • 恢复时不依赖外部记录
  • 保证对象内部状态的私有性(封装)

✅ 所以我们引入备忘录模式:由备忘录(Memento)保存对象状态,管理员(Caretaker)持有备忘录,对象(Originator)可保存/恢复。


二、结构图(UML)

+----------------+
| Originator     |
+----------------+
| +createMemento |
| +restore(m)    |
+----------------+|v
+----------------+
| Memento        |
+----------------+
|  state         |
+----------------+^|
+----------------+
| Caretaker      |
+----------------+
|  history       |
+----------------+

在这里插入图片描述

三、角色说明

角色说明
Originator发起人:定义要保存的状态,并创建和恢复备忘录
Memento备忘录:存储发起人对象的状态,不提供修改接口
Caretaker管理者:保存备忘录对象,不操作其内容,仅作管理使用

四、C++ 实现:文本编辑器 Undo 示例

我们模拟一个文本编辑器,每次输入文本都可以保存当前状态。

✅ Originator 类:TextEditor

class Memento {std::string state_;
public:Memento(const std::string& s) : state_(s) {}std::string getState() const { return state_; }
};class TextEditor {std::string text_;
public:void type(const std::string& newText) {text_ += newText;}std::shared_ptr<Memento> save() {return std::make_shared<Memento>(text_);}void restore(std::shared_ptr<Memento> m) {text_ = m->getState();}void show() const {std::cout << "当前内容:" << text_ << std::endl;}
};

✅ Caretaker:备忘录栈

class Caretaker {std::stack<std::shared_ptr<Memento>> history_;
public:void backup(std::shared_ptr<Memento> m) {history_.push(m);}std::shared_ptr<Memento> undo() {if (!history_.empty()) {auto m = history_.top();history_.pop();return m;}return nullptr;}
};

✅ 使用示例

int main() {TextEditor editor;Caretaker caretaker;editor.type("Hello ");caretaker.backup(editor.save());editor.type("World!");caretaker.backup(editor.save());editor.type(" This should be undone.");editor.show();editor.restore(caretaker.undo());editor.show();editor.restore(caretaker.undo());editor.show();return 0;
}

输出:

当前内容:Hello World! This should be undone.
当前内容:Hello World!
当前内容:Hello

五、实际项目中的应用场景

场景应用说明
编辑器(文本、图像)操作历史,撤销恢复
游戏进度管理存档机制,一键恢复到特定状态
配置参数修改一键还原到默认参数或历史设置
工作流状态保存在流程推进过程中保存流程中间状态
数据库事务管理快照、事务回滚

六、优缺点分析

✅ 优点:

  • 保留对象状态,支持撤销与恢复
  • 不破坏封装性,状态由对象自身保存
  • 多个备份版本可管理

❗ 缺点:

  • 状态快照可能占用较大内存
  • 多次保存增加性能开销
  • 管理复杂,需注意备份何时保存/清理

七、与命令、原型模式对比

模式意图特点
备忘录 Memento保存对象内部状态封装状态,支持恢复
命令 Command将操作封装为对象,支持撤销记录操作动作,而非对象状态本身
原型 Prototype克隆对象一般用于新对象创建,非状态回滚

八、面试回答模板

“我们在图像处理系统中使用备忘录模式保存图像编辑的中间状态。每次用户进行滤镜、剪裁、调整操作时,会生成一个状态快照,存入备忘录栈。当用户点击撤销时,恢复到上一个状态。该方案确保封装性,同时支持多层撤销。”

✅ 强调:状态封装、用户体验、栈式回滚逻辑


九、口诀记忆

“封装状态不泄露,快照回滚不出错;历史栈中找快照,一键恢复没烦恼。”


十、明日预告:Day 19

解释器模式(Interpreter Pattern):为语言构建解释器,对语法规则建模,实现表达式的解析与执行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/78626.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java单元测试代码

import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; import java.util.List;public class UserServiceTest {Testpublic void testSearchUserByTags() {// 模拟标签列表List<String> tagNameList List.of("tag1", "…

前端面经-VUE3篇(一)--vue3基础知识- 插值表达式、ref、reactive

目录 一、 插值表达式 1、插值表达式 ({{}}) 的本质与作用&#xff1a; 2、与 Vue 响应式系统关系&#xff1a; 二、指令 1、什么是 Vue 指令&#xff1f; 2、指令的分类 1、内置指令 ① 内容绑定&#xff1a;v-text 和 v-html ② 属性绑定&#xff1a;v-bind ③ 事件绑定…

矩阵置零(中等)

可以用两个标记数组分别记录每一行和每一列是否有零出现。 首先遍历该数组一次&#xff0c;如果某个元素为 0&#xff0c;那么就将该元素所在的行和列所对应标记数组的位置置为 true。然后再次遍历该数组&#xff0c;用标记数组更新原数组。 class Solution {public void set…

Android 实现一个隐私弹窗

效果图如下&#xff1a; 1. 设置同意、退出、点击用户协议、点击隐私协议的函数参数 2. 《用户协议》、《隐私政策》设置成可点击的&#xff0c;且颜色要区分出来 res/layout/dialog_privacy_policy.xml 文件 <?xml version"1.0" encoding"utf-8"?&…

TCP概念+模拟tcp服务器及客户端

目录 一、TCP基本概念 二、ser服务器代码 三、cil客户端代码 四、面试常问问题 4.1 TCP的可靠性怎么保证或怎么实现? 4.2 具体说一下滑动窗口 一、TCP基本概念 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可…

Cocos Creator 自动图集资源 (Auto Atlas)使用注意事项

1、游戏打包时&#xff0c;自动图集设置选项中&#xff0c;默认会删除无关联的图片 2、自动图集设置中&#xff0c;就算勾除(Remove unused ImageAsset from the Bundle)的功能&#xff0c;无关联的图片也不会打包进入图集之中&#xff0c;会独立存在打包的游戏中。 3、使用自动…

PyTorch 2.0编译器技术深度解析:如何自动生成高性能CUDA代码

引言&#xff1a;编译革命的范式转移 PyTorch 2.0的torch.compile不仅是简单的即时编译器&#xff08;JIT&#xff09;&#xff0c;更标志着深度学习框架从‌解释执行‌到‌编译优化‌的范式跃迁。本文通过逆向工程编译过程&#xff0c;揭示PyTorch如何将动态图转换为高性能CU…

【AI面试准备】从0-1搭建人工智能模型自动化评估理论与测试,掌握测试数据集建立与优化,熟练数据处理和模型评测工作

面试要求&#xff1a;从0-1搭建人工智能模型自动化评估理论与测试&#xff0c;掌握测试数据集建立与优化&#xff0c;熟练数据处理和模型评测工作。 以下是针对从0-1搭建AI模型自动化评估体系的系统化知识总结&#xff0c;涵盖核心方法论、技术栈、高频考点及面试回答模板&…

【Linux应用】在PC的Linux环境下通过chroot运行ARM虚拟机镜像img文件(需要依赖qemu-aarch64、不需要重新安装iso)

【Linux应用】在PC的Linux环境下通过chroot运行ARM虚拟机镜像img文件&#xff08;需要依赖qemu-aarch64、不需要重新安装iso&#xff09; qemu提供了运行ARM虚拟机的方法 具体的操作方式就是建立一个硬盘img 然后通过iso安装到img 最后再运行img即可 这种方式教程很多 很简单 …

OpenCv实战笔记(1)在win11搭建opencv4.11.1 + qt5.15.2 + vs2019_x64开发环境

一. 准备工作 Visual Studio 2019&#xff08;安装时勾选 C 桌面开发 和 Windows 10 SDK&#xff09; CMake 3.20&#xff08;官网下载&#xff09; Qt 5.15.2&#xff08;下载 Qt Online Installer&#xff09;安装时勾选 MSVC 2019 64-bit 组件。 opencv 4.11.1 源码下载 git…

springboot+mysql+element-plus+vue完整实现汽车租赁系统

目录 一、项目介绍 二、项目截图 1.项目结构图 三、系统详细介绍 管理后台 1.登陆页 2.管理后台主页 3.汽车地点管理 4.汽车类别 5.汽车品牌 6.汽车信息 7.用户管理 8.举报管理 9.订单管理 10.轮播图管理 11.交互界面 12.图表管理 汽车租赁商城 1.首页 2.汽…

【算法笔记】动态规划基础(二):背包dp

目录 01背包例题状态表示状态计算初始化AC代码 完全背包例题状态表示状态计算初始化TLE代码 多重背包例题状态表示状态计算初始化AC代码 分组背包例题状态表示状态计算初始化AC代码 二维费用背包例题状态表示状态计算初始化AC代码 混合背包问题例题状态表示状态计算初始化TLE代…

Qt Quick Design 下载社区版

官方地址&#xff1a;Qt Design Studio - UI Development Tool for Applications & Devices 社区版只能用于开源软件的开发 按图所示下载或直接跳转到下载页面&#xff1a;Download Qt OSS: Get Qt Online Installerhttps://www.qt.io/download-qt-installer-oss 选Try …

深入理解CSS盒子模型

一、盒子模型的核心概念 CSS盒子模型&#xff08;Box Model&#xff09;是网页布局的基石&#xff0c;每个HTML元素都可以看作一个矩形盒子&#xff0c;由四个同心区域构成&#xff1a; 内容区&#xff08;Content&#xff09; 内边距&#xff08;Padding&#xff09; 边框&a…

Python项目源码57:数据格式转换工具1.0(csv+json+excel+sqlite3)

1.智能路径处理&#xff1a;自动识别并修正文件扩展名&#xff0c;根据转换类型自动建议目标路径&#xff0c;实时路径格式验证&#xff0c;自动补全缺失的文件扩展名。 2.增强型预览功能&#xff1a;使用pandastable库实现表格预览&#xff0c;第三方模块自己安装一下&#x…

数据库MySQL学习——day9(聚合函数与分组数据)

文章目录 1. 聚合函数1.1 COUNT() 函数1.2 SUM() 函数1.3 AVG() 函数1.4 MIN() 函数1.5 MAX() 函数 2. GROUP BY 子句2.1 使用 GROUP BY 进行数据分组2.2 结合聚合函数 3. HAVING 子句3.1 使用 HAVING 过滤分组数据3.2 HAVING 和 WHERE 的区别 4. 实践任务4.1 创建一个销售表4.…

数据管理能力成熟度评估模型(DCMM)全面解析:标准深度剖析与实践创新

文章目录 一、DCMM模型的战略价值与理论基础1.1 DCMM的本质与战略定位1.2 DCMM的理论基础与创新点 二、DCMM模型的系统解构与逻辑分析2.1 八大能力域的有机关联与系统架构2.2 五级成熟度模型的内在逻辑与演进规律 三、DCMM八大能力域的深度解析与实践创新3.1 数据战略&#xff…

Docker搜索镜像报错

科学上网最方便。。。。 主要是镜像的问题 尝试一&#xff1a; 报错处理 Error response from daemon: Get https://index.docker.io/v1/search?qmysql&n25: dial tcp 31.13.84.2:443: i/o timeout Error response from daemon: Get https://index.docker.io/v1/se…

ERP系统源码,java版ERP管理系统源码,云端ERP

一套开箱即用的云端ERP系统源代码&#xff0c;小型工厂ERP系统源码 SaaS ERP是一套开箱即用的云端ERP系统&#xff0c;有演示&#xff0c;开发文档&#xff0c;数据库文档齐全&#xff0c;自主版权落地实例&#xff0c;适合项目二开。 SaaS ERP具有高度的灵活性和可扩展性&am…

Sliding Window Attention(Longformer)

最简单的自注意力大家肯定都会啦。 但这种全连接的自注意力&#xff08;即每个 token 需要 attend 到输入序列中的所有其他 token&#xff09;计算与内存开销是 O ( n 2 ) O(n^2) O(n2) 。为了缓解这个问题&#xff0c;研究者们提出了 Sliding Window Attention。 Sliding W…