找回密码
 立即注册
首页 业界区 业界 备忘录模式

备忘录模式

当贵 2025-6-6 14:46:34
备忘录(Memento、Snapshot)模式属于行为型模式的一种。
备忘录模式主要用于捕获一个对象的内部状态,以便在将来的某个时候恢复此状态。
备忘录模式的核心思想是将对象的状态保存在一个独立的对象中,这样既能保持对象的封装性,又能方便地恢复对象到之前的状态。
我们使用的几乎所有软件都用到了备忘录模式。大多数软件提供的保存、打开,以及编辑过程中的Undo、Redo都是备忘录模式的应用。Java的序列化也可以看作是备忘录模式。
备忘录模式适合在有撤销操作、恢复状态、对象状态追踪等场景下使用。
备忘录模式通常有以下组成部分:

  • Memento(备忘录):存储对象的内部状态。备忘录通常是一个不可变的对象,即在创建之后不允许更改它的内容。
  • Originator(发起人):发起人是需要保存其状态的对象。它创建一个备忘录,保存当前的状态,并可以通过备忘录恢复到之前的状态。发起人负责生成和恢复备忘录,但它对备忘录的内部状态一无所知。
  • Caretaker(看护者):看护者负责保存备忘录,但它不能修改备忘录的内容。看护者是一个管理者,通常用于保存多个备忘录的状态,供需要时进行恢复。
如果我们使用的编程语言支持嵌套类(如Java、C++、 C# 等),则可将备忘录嵌套在Originator类中; 如果不支持(如PHP等), 那么我们可以从备忘录类中抽取一个空接口,然后让其他所有对象通过接口来引用备忘录。 我们还可以在该接口中添加一些元数据操作,但不能暴露Originator类的状态。
我们用备忘录模式实现一个简单的文本编辑器中的撤销功能。当用户输入文本时,编辑器会保存当前文本状态,这样当用户点击“撤销”按钮时,编辑器能够恢复到上一个状态。
1、Memento: 备忘录类
  1. // Memento: 备忘录类
  2. class Memento {
  3.     private String state;
  4.     public Memento(String state) {
  5.         this.state = state;
  6.     }
  7.     public String getState() {
  8.         return state;
  9.     }
  10. }
复制代码
1.gif
2、Originator: 发起人类
  1. // Originator: 发起人类
  2. class TextEditor {
  3.     private String text;
  4.     public void setText(String text) {
  5.         this.text = text;
  6.     }
  7.     public String getText() {
  8.         return text;
  9.     }
  10.     // 创建备忘录
  11.     public Memento saveToMemento() {
  12.         return new Memento(text);
  13.     }
  14.     // 恢复状态
  15.     public void restoreFromMemento(Memento memento) {
  16.         this.text = memento.getState();
  17.     }
  18. }
复制代码
2.gif
3、Caretaker: 看护者类
  1. // Caretaker: 看护者类
  2. class TextEditorHistory {
  3.     private List<Memento> mementoList = new ArrayList<>();
  4.     // 保存备忘录
  5.     public void addMemento(Memento memento) {
  6.         mementoList.add(memento);
  7.     }
  8.     // 获取特定索引的备忘录
  9.     public Memento getMemento(int index) {
  10.         return mementoList.get(index);
  11.     }
  12. }
复制代码
3.gif
4、客户端
  1. // 客户端代码
  2. public class MementoPatternDemo {
  3.     public static void main(String[] args) {
  4.         TextEditor editor = new TextEditor();
  5.         TextEditorHistory history = new TextEditorHistory();
  6.         editor.setText("Hello");
  7.         history.addMemento(editor.saveToMemento()); // 保存当前状态
  8.         editor.setText("Hello, World!");
  9.         history.addMemento(editor.saveToMemento()); // 保存当前状态
  10.         editor.setText("Hello, World! How are you?");
  11.         System.out.println("Current Text: " + editor.getText());
  12.         // 恢复到上一个状态
  13.         editor.restoreFromMemento(history.getMemento(1));
  14.         System.out.println("After undo: " + editor.getText());
  15.         // 恢复到最初状态
  16.         editor.restoreFromMemento(history.getMemento(0));
  17.         System.out.println("After undo again: " + editor.getText());
  18.     }
  19. }
复制代码
4.gif
备忘录模式的优缺点
优点:

  • 保持封装性:备忘录模式允许将对象的状态保存在外部,但不暴露对象的内部实现。发起人对象可以将状态保存在备忘录中,而无需让其他对象直接访问内部状态。
  • 简化恢复操作:通过备忘录,系统可以轻松地将对象恢复到之前的状态,而无需手动追踪每个状态的变更。
  • 支持多次恢复:可以创建多个备忘录对象,用于在不同的时刻恢复到不同的状态。
缺点:

  • 增加了系统的复杂性:备忘录模式涉及多个对象的协作,可能会导致系统设计更加复杂。
  • 内存消耗大:每次状态变更都会创建一个新的备忘录,这可能导致内存消耗较大,尤其是状态变化频繁时。
  • 备忘录管理问题:如果管理不当,备忘录可能会堆积成大量的无用对象,需要额外的清理策略。
我们可以同时使用命令模式备忘录模式来实现 “撤销”功能。命令用于对目标对象执行各种不同的操作,备忘录用来保存一条命令执行前该对象的状态。
人生的确充满艰难险阻,但回荡不息的主旋律,是不期而遇的温暖和生生不息的希望。-- 烟沙九洲

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册