Skip to content

备忘录模式

不破坏对象封装的前提下,保存和恢复对象的状态。

适用的场景

  • 需要保存某个对象某一时刻的状态,并在之后可以恢复

  • 不想暴露对象内部的实现细节

  • 通常用于撤销(undo)机制、历史记录、状态回滚等功能

比如编辑器的撤销、游戏的存档系统、AI决策回退等都用它

基本结构

  • Originator(原发器):拥有要保存状态的对象,能生成/恢复备忘录

  • Memento(备忘录):存储 Originator 的状态,不提供修改

  • Caretaker(管理者):负责存取备忘录,但不能操作内容(守规矩!)

示例

c#
// 备忘录
class EditorMemento 
{
    public string Text { get; }

    public EditorMemento(string text) 
    {
        Text = text;
    }
}

// 原发器
class TextEditor 
{
    private string _text = "";

    public void Type(string input) 
    {
        _text += input;
    }

    public string GetText() => _text;

    public EditorMemento Save() => new EditorMemento(_text);

    public void Restore(EditorMemento memento) 
    {
        _text = memento.Text;
    }
}

// 管理者
class History 
{
    private Stack<EditorMemento> _stack = new();

    public void Push(EditorMemento memento) => _stack.Push(memento);
    public EditorMemento Pop() => _stack.Pop();
}

// 使用:
var editor = new TextEditor();
var history = new History();

editor.Type("Hello");
history.Push(editor.Save());

editor.Type(" World!");
Console.WriteLine(editor.GetText()); // Hello World!

editor.Restore(history.Pop());
Console.WriteLine(editor.GetText()); // Hello

GDScript示例

gdscript
class Memento:
    var state: String

class Originator:
    var _state: String

    func set_state(s):
        _state = s

    func get_state() -> String:
        return _state

    func save() -> Memento:
        var m = Memento.new()
        m.state = _state
        return m

    func restore(m: Memento):
        _state = m.state

class Caretaker:
    var history: Array = []

    func backup(m: Memento):
        history.append(m)

    func undo() -> Memento:
        return history.pop_back()

func _ready():
    var origin = Originator.new()
    var caretaker = Caretaker.new()
    
    origin.set_state("状态A")
    caretaker.backup(origin.save())
    
    origin.set_state("状态B")
    print(origin.get_state()) # 状态B
    
    origin.restore(caretaker.undo())
    print(origin.get_state()) # 状态A