设计模式-备忘录模式(Memento Pattern)结构|原理|优缺点|场景|示例

备忘录模式(Memento Pattern)是一种行为设计模式,它提供了一种在不破坏封装性的前提下,捕获并外部化对象的内部状态,并能在需要时恢复该对象状态的方法。这种模式主要用于实现撤销操作,回滚到之前的状态,或者记录一个对象的一系列状态,以便将来恢复。

结构: 备忘录模式包含以下几个主要角色:

  1. Originator(发起人):创建并保存其内部状态的快照,同时定义恢复状态的方法。
  2. Memento(备忘录):存储Originator对象的内部状态,但对外界隐藏具体实现细节,只暴露有限的接口防止外部对状态的非法访问。
  3. Caretaker(管理者/保姆):负责持有Memento对象,不直接访问Memento的内容,只是简单地存储和提供给Originator。

原理:

  • 发起人(Originator)在需要保存状态时,创建一个备忘录(Memento)对象,该对象包含了发起人的当前状态。
  • 发起人将备忘录对象传递给管理者(Caretaker)保管,但不暴露备忘录的具体实现细节。
  • 当需要恢复状态时,发起人从管理者那里取回备忘录对象,并根据其中的信息恢复到之前的状态。

优缺点: 优点:

  • 提供了状态恢复的能力,使得用户可以方便地回到某个历史状态。
  • 改善了封装性,状态的存储由备忘录对象管理,外部对象无法直接访问内部状态。
  • 支持撤销操作,增强了系统的灵活性和可维护性。

缺点:

  • 如果状态数据庞大,可能会占用大量的存储空间。
  • 需要谨慎管理备忘录,避免无限制增长导致资源消耗问题。
  • 增加了系统的复杂度,特别是在需要管理多个状态版本的情况下。

应用场景:

  • 文档编辑器中的撤销/重做功能。
  • 游戏中的存档/读档功能。
  • 配置设置的保存与恢复。
  • 事务处理中的回滚机制。

代码示例(以Java为例)

// Memento类,存储Originator的状态
class TextEditorMemento {
    private String content;
    
    public TextEditorMemento(String content) {
        this.content = content;
    }
    
    String getContent() {
        return content;
    }
}

// Originator类,即文本编辑器
class TextEditor {
    private String content;
    
    public void type(String text) {
        content += text;
        System.out.println("Typed: " + text);
    }
    
    public TextEditorMemento save() {
        return new TextEditorMemento(content);
    }
    
    public void restore(TextEditorMemento memento) {
        content = memento.getContent();
        System.out.println("Restored: " + content);
    }
}

// Caretaker类,负责存储Mementos
class Caretaker {
    private List<TextEditorMemento> history = new ArrayList<>();
    
    void addMemento(TextEditorMemento memento) {
        history.add(memento);
    }
    
    TextEditorMemento getMemento(int index) {
        return history.get(index);
    }
}

// 使用示例
public class MementoDemo {
    public static void main(String[] args) {
        TextEditor editor = new TextEditor();
        Caretaker caretaker = new Caretaker();
        
        editor.type("Hello, ");
        caretaker.addMemento(editor.save());
        
        editor.type("World!");
        caretaker.addMemento(editor.save());
        
        editor.type(" How are you?");
        System.out.println("Current text: " + editor.getContent());
        
        editor.restore(caretaker.getMemento(1));
        System.out.println("After restore: " + editor.getContent());
    }
}

 在这个例子中,TextEditor作为发起人,记录并恢复文本状态;TextEditorMemento是备忘录,保存了文本内容;Caretaker作为管理者,存储并提供备忘录。通过这样的设计,我们可以轻松实现文本编辑器的撤销功能。

上一篇:vue都有那些指令?


下一篇:AWS制作WordPress在国内外的利弊?