欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > 备忘录模式

备忘录模式

2025/4/19 16:26:34 来源:https://blog.csdn.net/Android_xue/article/details/142773926  浏览:    关键词:备忘录模式

简介

备忘录模式(Memento Pattern)又叫作快照模式(Snapshot Pattern)或令牌模式(Token Pattern),指在不破坏封装的前提下,捕获一个对象的内部状态,并在对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态,属于行为型设计模式。

通用模板

  1. 创建备忘录角色:用于存储Originator(发起人角色)的内部状态,且可以防止Originator以外的对象进行访问。

    // 备忘录
    public class Memento {private String state;public Memento(String state) {this.state = state;}public String getState() {return this.state;}
    }
    
  2. 创建发起人角色:负责创建一个备忘录,记录自身需要保存的状态;具备状态回滚功能。

    // 发起人
    public class Originator {// 内部状态private String state;public String getState() {return this.state;}public void setState(String state) {this.state = state;}// 创建一个备忘录public Memento createMemento() {return new Memento(this.state);}// 从备忘录恢复public void restoreMemento(Memento memento) {this.state = memento.getState();}
    }
    
  3. 创建备忘录管理者角色:负责存储、提供管理Memento(备忘录),无法对Memento的内容进行操作和访问。

    // 备忘录管理者
    public class Caretaker {// 备忘录对象private Memento memento;public Memento getMemento() {return this.memento;}public void storeMemento(Memento memento) {this.memento = memento;}
    }
    

模板测试

  1. 测试代码

    public class Client {public static void main(String[] args) {// 创建一个发起人角色Originator originator = new Originator();// 创建一个备忘录管理员角色Caretaker caretaker = new Caretaker();// 设置初始状态originator.setState("状态A");System.out.println("初始状态:" + originator.getState());// 保存当前状态caretaker.storeMemento(originator.createMemento());// 更改状态originator.setState("状态B");System.out.println("更改后的状态:" + originator.getState());// 恢复到之前的状态originator.restoreMemento(caretaker.getMemento());System.out.println("恢复后的状态:" + originator.getState());}
    }
    
  2. 测试结果

    初始状态:状态A
    更改后的状态:状态B
    恢复后的状态:状态A
    

应用场景

对于程序员来说,可能天天都在使用备忘录模式,比如我们每天使用的Git、SVN都可以提供一种代码版本撤回的功能。还有一个比较贴切的现实场景就是游戏的存档功能,通过将游戏当前进度存储到本地文件系统或数据库中,使得下次继续游戏时,玩家可以从之前的位置继续进行。
备忘录模式主要适用于以下应用场景。
(1)需要保存历史快照的场景。
(2)希望在对象之外保存状态,且除了自己,其他类对象无法访问状态保存的具体内容。

优点

(1)简化发起人实体类(Originator)的职责,隔离状态存储与获取,实现了信息的封装,客户端无须关心状态的保存细节。
(2)提供状态回滚功能。

缺点

备忘录模式的缺点主要是消耗资源。如果需要保存的状态过多,则每一次保存都会消耗很多内存。

“生搬硬套”实战

场景描述

假设你在编写一个文本编辑器应用程序,用户在编辑文档时,希望能够随时保存当前编辑的状态,并在需要时恢复到之前保存的状态。这就需要用到备忘录模式来实现撤销功能。

代码开发
  1. 创建备忘录角色(这里指用来存储文档的状态的备忘录)

    // 定义一个备忘录类来存储文档的状态
    public class DocumentMemento {private String content;public DocumentMemento(String content) {this.content = content;}public String getContent() {return content;}
    }
    
  2. 创建发起人角色(这里指文档编辑器)

    // 发起人角色(Originator),也就是我们的文档编辑器,它负责创建备忘录并恢复状态
    public class DocumentEditor {private String content;public void setContent(String content) {this.content = content;}public String getContent() {return content;}// 创建备忘录public DocumentMemento createMemento() {return new DocumentMemento(content);}// 从备忘录恢复状态public void restoreFromMemento(DocumentMemento memento) {this.content = memento.getContent();}
    }
    
  3. 创建备忘录管理者角色(这里指存储文档备忘录的管理类)

    import java.util.ArrayList;
    import java.util.List;// 管理者角色(Caretaker),它用来存储备忘录对象
    public class DocumentCaretaker {private List<DocumentMemento> mementos = new ArrayList<>();public void addMemento(DocumentMemento memento) {mementos.add(memento);}public DocumentMemento getMemento(int index) {return mementos.get(index);}
    }
    

至此,我们就通过“生搬硬套”备忘录模式的模板设计出一套文档备忘录的案例,接下来我们进行测试:

  • 测试代码

    public class Test {public static void main(String[] args) {// 创建一个发起人角色DocumentEditor editor = new DocumentEditor();// 创建一个备忘录管理员角色DocumentCaretaker caretaker = new DocumentCaretaker();// 设置初始文档内容editor.setContent("Hello, ");System.out.println("初始文档内容: " + editor.getContent());// 保存当前状态caretaker.addMemento(editor.createMemento());// 更改文档内容editor.setContent(editor.getContent() + "World!");System.out.println("更改后文档内容: " + editor.getContent());// 恢复到之前的状态editor.restoreFromMemento(caretaker.getMemento(0));System.out.println("恢复后的文档内容: " + editor.getContent());}
    }
    
  • 测试结果

    初始文档内容: Hello, 
    更改后文档内容: Hello, World!
    恢复后的文档内容: Hello, 
    

总结

备忘录模式的本质是从发起人实体类(Originator)隔离存储功能,降低实体类的职责。同时由于存储信息(Memento)独立,且存储信息的实体交由管理类(Caretaker)管理,则可以通过为管理类扩展额外的功能对存储信息进行扩展操作(比如增加历史快照功能)。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词