设计模式学习(21) 23-19 备忘录模式

文章目录

  • 0. 个人感悟
  • 1. 概念
  • 2. 适配场景
    • 2.1 适合的场景
    • 2.2 常见场景举例
  • 3. 实现方法
    • 3.1 实现思路
    • 3.2 UML类图
    • 3.3 代码示例
  • 4. 优缺点
    • 4.1 优点
    • 4.2 缺点
  • 5. 源码分析
    • 5.1 Java Swing中的UndoManager

0. 个人感悟

  • 备忘录模式的场景也比较专。适合进行备份、恢复
  • 模式优点很明显,状态保存于业务逻辑分离,实现解耦
  • 一个注意的点是窄接口设计,Memento(备忘录)内部保存了Originator(原发器)的状态,但这个状态不应该被除了Originator之外的其他对象(特别是Caretaker)直接访问或修改,以保护状态的封装性。具体可以看看示例代码

1. 概念

英文定义(《设计模式:可复用面向对象软件的基础》)

Without violating encapsulation, capture and externalize an object,t internal state so that the object can be restored this state later.

中文翻译

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后可以将对象恢复到原先保存的状态。

理解

  • 备忘录模式提供了一种状态恢复机制,允许对象回到某个历史状态
  • 它通过独立的对象(备忘录)来存储状态,而不是由原对象自己保存
  • 实现了状态保存与业务逻辑的分离,原对象专注于业务,管理者专注于状态管理

2. 适配场景

2.1 适合的场景

  1. 需要撤销/重做功能:如文本编辑器、绘图软件的操作历史
  2. 需要保存快照/检查点:如游戏存档、系统配置备份
  3. 状态转换复杂:如工作流引擎的状态管理
  4. 需要事务回滚:如数据库操作的事务管理
  5. 原型状态保存:如复杂对象构造过程中的中间状态保存
  6. 需要版本控制:如文档编辑的历史版本管理

2.2 常见场景举例

  1. IDE开发环境:Eclipse/IntelliJ IDEA的代码编辑撤销功能
  2. 绘图软件:Photoshop的历史记录面板
  3. 游戏开发:游戏进度存档/读档系统
  4. 表单应用:多步表单的回退功能
  5. 配置管理:系统配置的备份与恢复
  6. 数据库系统:事务的rollback机制

3. 实现方法

3.1 实现思路

  1. 识别状态数据:确定需要保存的内部状态字段
  2. 创建Memento类:设计存储状态的数据结构
  3. 在Originator中添加状态管理
    • 创建保存状态的方法(saveToMemento()
    • 创建恢复状态的方法(restoreFromMemento()
  4. 设计Caretaker类
    • 决定存储策略(栈、列表、树等)
    • 实现状态管理逻辑(撤销、重做、清空等)
  5. 控制访问权限
    • 对Originator开放宽接口(可读写状态)
    • 对Caretaker开放窄接口(只读元数据)

3.2 UML类图

角色说明:

  • Originator(原发器):需要保存状态的对象,负责创建和恢复备忘录
  • Memento(备忘录):存储Originator内部状态,通常设计为不可变对象
  • Caretaker(管理者):负责保存和管理备忘录,但不能操作备忘录内容

3.3 代码示例

背景
以文件编辑器为例,简化业务,只有保存和撤销功能
设计

原发器

publicclassTextEditor{privateStringcontent;publicStringgetContent(){returncontent;}publicvoidsetContent(Stringcontent){this.content=content;}publicTextEditor(Stringcontent){this.content=content;}/** * @description 创建备忘 * @author bigHao * @date 2026/1/27 * @return designpattern.memento.pac.TextMemento 备忘录 **/publicTextMementocreateMemento(){returnnewTextMemento(content);}/** * @description 恢复备忘 * @author bigHao * @date 2026/1/27 * @param memento 备忘录 **/publicvoidrestoreMemento(TextMementomemento){this.content=memento.getContent();}}

备忘录

  • 注意权限控制。备忘录只有原发器可以创建和访问内容。实际操作中将二者放到一个包下,相关方法使用包权限
publicclassTextMemento{privateStringcontent;// 包访问权限,仅对Originator开放状态访问TextMemento(Stringcontent){this.content=content;}StringgetContent(){returncontent;}}

管理者

publicclassCaretaker{privatestaticfinalintMAX_SIZE=100;// 业务场景刚好使用stack 先进后出privateStack<TextMemento>history=newStack<>();publicvoidpush(TextMementomemento){// 限制下长度limitHistory();this.history.push(memento);}publicTextMementopop(){returnthis.history.pop();}privatevoidlimitHistory(){if(history.size()>MAX_SIZE){history.removeFirst();}}}

测试

publicclassClient{staticvoidmain(){// 创建Stringcontent="备忘录模式笔记";TextEditortextEditor=newTextEditor(content);printInfo(textEditor);Caretakercaretaker=newCaretaker();// 安全考虑,TextMemento是包访问权限,和TextEditor同包,其它地方无法直接创建// new TextMemento(""); 会报错// 保存1caretaker.push(textEditor.createMemento());content+="包括三个角色,分别是原发器";textEditor.setContent(content);caretaker.push(textEditor.createMemento());printInfo(textEditor);// 保存2content+="、备忘录";textEditor.setContent(content);caretaker.push(textEditor.createMemento());printInfo(textEditor);// 保存3content+="和管理者";textEditor.setContent(content);caretaker.push(textEditor.createMemento());printInfo(textEditor);// 编辑content+=" 功能分别是";textEditor.setContent(content);printInfo(textEditor);// 撤销1System.out.println("===撤销===");textEditor.restoreMemento(caretaker.pop());printInfo(textEditor);// 撤销2System.out.println("===撤销===");textEditor.restoreMemento(caretaker.pop());printInfo(textEditor);}privatestaticvoidprintInfo(TextEditortextEditor){System.out.println("当前内容: "+textEditor.getContent());}}

输出

当前内容: 备忘录模式笔记 当前内容: 备忘录模式笔记包括三个角色,分别是原发器 当前内容: 备忘录模式笔记包括三个角色,分别是原发器、备忘录 当前内容: 备忘录模式笔记包括三个角色,分别是原发器、备忘录和管理者 当前内容: 备忘录模式笔记包括三个角色,分别是原发器、备忘录和管理者 功能分别是 ===撤销=== 当前内容: 备忘录模式笔记包括三个角色,分别是原发器、备忘录和管理者 ===撤销=== 当前内容: 备忘录模式笔记包括三个角色,分别是原发器、备忘录

4. 优缺点

4.1 优点

高内聚低耦合

  • 职责分离:状态保存与业务逻辑解耦,Originator只关注核心功能
  • 封装性:通过窄接口模式保护状态不被Caretaker误操作

复用性

  • 状态管理可复用:Caretaker可被多个Originator复用
  • 存储策略灵活:支持栈、列表、数据库等多种存储方式

可读性

  • 意图明确:代码明确表达了"保存状态"和"恢复状态"的意图
  • 结构清晰:三个角色分工明确,易于理解

维护性

  • 易于扩展:可轻松添加新的存储策略或状态类型
  • 修改隔离:状态存储逻辑变化不影响Originator

稳定性

  • 状态一致:确保状态恢复的正确性
  • 异常安全:状态操作失败时可恢复到之前状态

4.2 缺点

资源消耗

  • 内存占用:大量状态保存可能导致内存消耗过大
  • 性能开销:频繁的状态保存/恢复可能影响性能

设计复杂度

  • 额外类:增加了Memento和Caretaker类
  • 窄接口实现复杂:需要小心设计访问权限

状态同步

  • 深拷贝问题:复杂对象的深拷贝可能实现复杂
  • 版本兼容:状态数据结构变化时,旧备忘录可能无法恢复

5. 源码分析

5.1 Java Swing中的UndoManager

代码位置javax.swing.undo.UndoManager

角色分析

// Originator:各种Document类(如PlainDocument)publicclassPlainDocumentextendsAbstractDocument{// 创建UndoableEdit(备忘录)protectedUndoableEditcreateUndoableEdit(ElementChangeec){returnnewDocumentUndoableEdit(ec);}}// Memento:UndoableEdit接口及其实现publicinterfaceUndoableEdit{voidundo()throwsCannotUndoException;voidredo()throwsCannotRedoException;booleancanUndo();booleancanRedo();}// Caretaker:UndoManager类publicclassUndoManagerextendsCompoundEditimplementsUndoableEditListener{privateVector<UndoableEdit>edits;// 存储备忘录privateintindexOfNextAdd;// 下一个添加位置publicvoidundo()throwsCannotUndoException{// 执行撤销操作UndoableEditedit=edits.elementAt(--indexOfNextAdd);edit.undo();}publicvoidredo()throwsCannotRedoException{// 执行重做操作UndoableEditedit=edits.elementAt(indexOfNextAdd);edit.redo();indexOfNextAdd++;}}

参考:

  • 韩顺平 Java设计模式
  • 归思君 设计模式学习笔记(十八)备忘录模式及其实现
  • kosamino 设计模式之备忘录模式(Memento)详解及代码示例

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

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

相关文章

d3dcompiler_47.dll缺失怎么修复 免费下载文件方法分享

在使用电脑系统时经常会出现丢失找不到某些文件的情况&#xff0c;由于很多常用软件都是采用 Microsoft Visual Studio 编写的&#xff0c;所以这类软件的运行需要依赖微软Visual C运行库&#xff0c;比如像 QQ、迅雷、Adobe 软件等等&#xff0c;如果没有安装VC运行库或者安装…

【Django毕设全套源码+文档】基于Django框架的贵州特色产品销售平台的设计与实现(丰富项目+远程调试+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

VSCode 附加进程调试完整指南

目录 概述附加调试 vs 启动调试配置说明使用方法常见场景调试技巧故障排除 概述 附加进程调试&#xff08;Attach Debugging&#xff09;是一种强大的调试技术&#xff0c;允许调试器附加到已经运行的进程上&#xff0c;而不需要从调试器启动程序。这在以下场景特别有用&…

2026年中国留学生求职机构推荐:行业应用深度评测直击适配与内推关键痛点

摘要 在全球化人才流动与国内就业市场竞争加剧的双重背景下,中国留学生群体正面临前所未有的职业发展抉择。无论是寻求在留学地积累国际经验,还是规划学成归国发展,如何精准对接目标企业与岗位,已成为横亘在数十万…

2026年行业内优秀的冷却塔品牌怎么选,玻璃钢冷却塔/冷却塔/工业冷却塔/圆形逆流冷却塔,冷却塔制造厂家排行榜

随着工业4.0与“双碳”目标的推进,冷却塔作为工业循环水系统的核心设备,其技术迭代与服务质量直接影响企业的能耗成本与生产效率。当前,市场对冷却塔的需求已从单一降温功能转向高效节能、低噪环保、智能运维的综合…

实验台哪家强?五大口碑品牌深度解析,总有一款适配你的科研需求

实验台作为实验室的核心基础设施,是保障科研、检测、教学工作高效开展的“基石”,其品质直接关乎实验安全、数据准确性与长期使用成本。随着国内科研投入加码、实验室合规要求升级,市场对实验台的智能化、环保性、定…

五恒系统厂商推荐,性价比高的公司有哪些?

随着人们对居住舒适度要求的不断提升,五恒系统逐渐成为住宅和别墅的标配。在选择五恒系统时,消费者往往面临品牌混乱、技术复杂、决策成本高等问题,因此找到一个可靠的五恒系统实力厂商至关重要。浙江丹特卫顿环境科…

2026年美国求职机构推荐:留学生求职市场排名,涵盖科技金融行业与OPT痛点

研究概述 随着全球人才流动加速与国际教育普及,寻求在美就业已成为众多国际留学生及海外专业人士的核心职业规划路径。这一趋势背后,是决策者面对复杂多变的美国就业市场、严格的签证政策、差异化的职场文化以及激烈…

VSCode,Claude 插件使用第三方 API 总是提示登录?

问题描述: Claude Code 2.0 版本更新后,VSCode 插件启用了强制登录验证,要求使用官方账号,导致第三方中转 API 无法使用 VSCode 中的 Claude 插件。如下图所示。解决方法: 通过修改 settings.json 来绕过登录限制…

聊聊新中式铝艺影壁墙服务商怎么选,哪家值得推荐

随着人们对庭院美学与功能性需求的提升,户外庭院铝艺影壁墙逐渐成为别墅、酒店、景区等空间的门面担当。作为兼具隔断、装饰与文化表达功能的核心构件,越来越多业主、设计师和工程商开始关注户外庭院铝艺影壁墙源头厂…

东岳搬家联系方式:评估搬家服务前的实用信息

一、官方联系方式 全国统一服务热线 4008860511 二、使用建议与提醒 第一点,在预约搬家服务前,建议进行充分的准备工作。这包括自行清点需要搬运的物品数量与类型,特别是大件家具、易碎品或特殊物品。明确搬运的起始…

定制门窗一线品牌贝克洛多少钱,价格合理吗

在选择门窗时,许多消费者和开发商都会优先考虑定制门窗一线品牌、门窗一线品牌推荐供应商、一线门窗品牌,这些关键词背后是对产品品质、性能和服务的高要求。贝克洛作为定制门窗一线品牌中的佼佼者,凭借多年的技术积…

2026年官厅中华永久陵园电话推荐:基于场景与合规评测,解决信息查询与交通痛点

摘要 在生命服务领域,选择一处适宜的安息之地是家庭面临的重要决策,这一过程往往伴随着信息搜寻、实地考察与综合比较的复杂流程。决策者不仅需要考量地理位置、环境风貌等感性因素,更需系统评估服务机构的合规性、…

分析皖南电机定制专家,性价比高的是哪家

2025年工业制造绿色转型加速,电机作为工业生产的核心动力设备,其能效水平、定制适配性直接影响企业的能耗成本与生产效率。无论是高性价比的标准电机采购、适配特殊工况的定制化电机方案,还是符合双碳政策的绿色电机…

2026年美国求职机构推荐:聚焦科技金融行业评价,针对OPT与H1B核心痛点指南

摘要 在全球化人才流动与竞争日益加剧的背景下,寻求海外职业发展,特别是进入美国就业市场,已成为众多国际学生与专业人士的关键战略选择。然而,目标决策者——尤其是计划或正在美国留学的学生及其家庭——面临着信…

涨跌停股票实时数据API接口汇总

涨跌停板API 1、涨停板 获取盘中涨停板实时数据。 数据更新:实时数据交易时间段每1分钟更新,历史数据收盘后3:30更新。 示例请求 GET http://api.fxyz.site/wolf/zt?tradeDate=2026-01-19&token= 返回字段参数 …

全国雅思培训排行推荐:2026权威出国雅思课程中心学校口碑排行榜

在雅思培训市场鱼龙混杂的当下,无数考生深陷选课迷茫、提分艰难的困境:优质教育机构甄别不易,各类课程宣传真假难辨,想要找到权威实用的备考方案,实现高分突破,却苦于缺乏全面深度的测评参考。对于不同基础的考生…

大语言模型演进史丨智能涌现之后,路在何方?(上)

‍自人类文明诞生以来,语言一直是知识传承与思想交流的核心载体。如何让机器理解并生成人类语言,成为人工智能领域最富挑战性的课题之一。 大语言模型(Large Language Models,LLMs)的崛起标志着自然语言处理领域的…

全国雅思培训排行推荐-2026权威出国雅思课程中心学校口碑排行榜

在出国留学热潮持续升温的背景下,雅思考试已成为通往海外院校的关键门槛,而雅思培训选课却成为多数考生及家长的核心痛点。市面上教育机构鱼龙混杂,考生往往在优质课程筛选、高分提分技巧获取、高性价比方案选择中陷…

解析CI/CD工具TeamCity的可视化失败追踪功能

在日常的持续集成流程中&#xff0c;构建失败往往是工程团队首先关注的反馈信号&#xff0c;为了真正理解构建失败背后的质量问题&#xff0c;CI/CD平台TeamCity提供了一套可视化的统计图表机制&#xff0c;让质量指标不再依赖日志分析或直觉判断。 >>最新版本CI/CD工具T…