资讯动态

设计模式行为型——备忘录模式

发布时间:2026/8/22 12:07:59 来源:尧图企业网站定制
目录备忘录模式的定义备忘录模式的实现备忘录模式角色备忘录模式类图备忘录模式举例备忘录模式代码实现备忘录模式的特点优点缺点使用场景注意事项实际应用备忘录模式的定义备忘录模式Memento Pattern又叫做快照模式Snapshot Pattern或Token模式Token Pattern属于行为型设计模式。在不破坏封闭的前提下捕获一个对象的内部状态并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。备忘录模式提供了一种状态恢复的实现机制使得用户可以方便地回到一个特定的历史步骤当新的状态无效或者存在问题时可以使用暂时存储起来的备忘录将状态复原当前很多软件都提供了撤销操作其中就使用了备忘录模式。备忘录模式的实现备忘录模式角色原发器角色Originator负责创建一个备忘录记录当前时刻的内部状态信息提供创建备忘录和恢复备忘录数据的功能实现其他业务功能它可以访问备忘录里的所有信息。同时原发器还可以根据需要决定Memento存储Originator的那些内部状态。备忘录角色Memento负责存储Originator对象的内部状态并可以防止Originator以外的其他对象访问备忘录。备忘录有两个接口Caretaker只能看到备忘录的窄接口他只能将备忘录传递给其他对象。Originator却可看到备忘录的宽接口允许它访问返回到先前状态所需要的所有数据。管理者角色Caretaker管理者又称为负责人它负责保存备忘录。在管理者类中可以存储一个或多个备忘录对象它只负责存储对象而不能修改对象负责任类只提供备忘录对象的读写接口不提供备忘录属性的读写接口也无须知道对象的实现细节。管理者对象可以保存一个备忘录数组从而实现原发器的多次撤销。其存储这些状态信息除了原发器外其他对象都是不可以访问的否则就违反了封装的原则。所以为了实现备忘录模式的封装需要对备忘录的访问做些控制对原发器可以访问备忘录里的所有信息。对管理者不可以访问备忘录里面的数据但是他可以保存备忘录并且可以将备忘录传递给其他对象。其他对象不可访问也不可以保存它只负责接收从负责人那里传递过来的备忘录同时恢复原发器的状态。所以就备忘录模式而言理想的情况就是只允许生成该备忘录的那个原发器访问备忘录的内部状态。备忘录模式类图备忘录模式举例要开发一个简单的草稿箱功能假设只保留文档标题和正文那么文档标题和正文就属于原发器角色还需要创建一个文章备忘录和一个草稿箱作为管理者角色保存历史文章信息。文章备忘录 包含了要被恢复的对象的状态。编辑器 创建并在 文章备忘录 对象中存储状态。草稿箱 对象负责从 文章备忘录 中恢复对象的状态。备忘录模式代码实现原发器角色package com.common.demo.pattern.memento; /** * author Evan Walker 昂焱数据: https://www.ayshuju.com * version 1.0 * desc 原发器角色 - 编辑器 * date 2023/08/05 10:26:52 */ public class Editor { private String title; private String content; public Editor() { } public Editor(String title, String content) { this.title title; this.content content; } public String getTitle() { return title; } public void setTitle(String title) { this.title title; } public String getContent() { return content; } public void setContent(String content) { this.content content; } public ArticleMemento saveToMemento(){ ArticleMemento articleMemento new ArticleMemento(this.title, this.content); return articleMemento; } public void undoFromMemento(ArticleMemento articleMemento){ this.title articleMemento.getTitle(); this.content articleMemento.getContent(); } Override public String toString() { return Editor{ title title \ , content content \ }; } }备忘录角色package com.common.demo.pattern.memento; /** * author Evan Walker 昂焱数据: https://www.ayshuju.com * version 1.0 * desc 备忘录角色 - 文章 * date 2023/08/05 10:28:21 */ public class ArticleMemento { // 标题 private String title; // 正文 private String content; public ArticleMemento() { } public ArticleMemento(String title, String content) { this.title title; this.content content; } public String getTitle() { return title; } public void setTitle(String title) { this.title title; } public String getContent() { return content; } public void setContent(String content) { this.content content; } }管理者角色package com.common.demo.pattern.memento; import java.util.Stack; /** * author Evan Walker 昂焱数据: https://www.ayshuju.com * version 1.0 * desc 管理员角色 - 草稿箱 * date 2023/08/05 10:30:41 */ public class DraftsBox { // 存储 - 后进先出 private final StackArticleMemento STACK new Stack(); public ArticleMemento getMemento() { ArticleMemento articleMemento STACK.pop(); return articleMemento; } public void addMemento(ArticleMemento articleMemento) { STACK.push(articleMemento); } }测试类package com.common.demo.pattern.memento; /** * author Evan Walker 昂焱数据: https://www.ayshuju.com * version 1.0 * desc 测试类 * date 2023/08/05 10:31:12 */ public class Test { public static void main(String[] args) { DraftsBox draftsBox new DraftsBox(); Editor editor new Editor(初始化, 首次发表); ArticleMemento articleMemento editor.saveToMemento(); draftsBox.addMemento(articleMemento); System.out.println(--------第一次编辑保存草稿之后信息如下---------); System.out.println(editor); editor.setTitle(第一次修改); editor.setContent(首次发表后第一次修改); ArticleMemento articleMemento1 editor.saveToMemento(); draftsBox.addMemento(articleMemento1); System.out.println(--------第一次修改保存草稿之后信息如下---------); System.out.println(editor); editor.setTitle(第二次修改); editor.setContent(首次发表后第二次修改); System.out.println(--------第一次修改还没保存草稿信息如下---------); System.out.println(editor); System.out.println(-------撤销操作---------); ArticleMemento memento draftsBox.getMemento(); editor.undoFromMemento(memento); System.out.println(--------第一次撤销之后信息如下---------); System.out.println(editor); ArticleMemento memento2 draftsBox.getMemento(); editor.undoFromMemento(memento2); System.out.println(--------第二次撤销之后信息如下---------); System.out.println(editor); } }测试截图备忘录模式的特点优点提供了对象状态的存储与恢复机制备忘录模式可以将对象的内部状态保存在备忘录中当需要时能够比较方便地将数据恢复到某个历史的状态。实现了内部状态的封装除了创建它的发起人之外其他对象都不能够访问这些状态信息。支持多次撤销和恢复操作备忘录模式可以保存多个状态快照使得客户端可以根据需求选择恢复到某个特定的状态。缺点资源消耗大如果要保存的内部状态信息过多或者特别频繁将会占用比较大的内存资源。对象状态的存储和恢复需要时间和计算资源备忘录模式需要对对象状态进行序列化和反序列化操作可能需要消耗一定的时间和计算资源。使用场景需要在不破坏对象封装性的前提下保存和恢复对象的状态。需要实现多级撤销和恢复操作。需要保存对象历史状态以供分析和审计。注意事项注意备忘录对象的生命周期管理避免资源泄露和内存溢出。确保备忘录对象只被相关的原发器对象访问避免违反封装原则。为了节约内存可使用原型模式备忘录模式。实际应用文本编辑器可以使用备忘录模式来实现文本编辑器的撤销和恢复功能将文本的不同版本保存在备忘录中。游戏进度保存与加载游戏中可以使用备忘录模式来保存和加载游戏的进度使得玩家可以随时恢复到之前的某个状态。软件撤销和恢复功能一些软件工具或者编辑器可以使用备忘录模式来实现撤销和恢复功能保存用户对文件的修改历史。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价