Skip to content

备忘录模式

备忘录模式(Memento Pattern)是一种行为设计模式,它允许对象在不影响其封装性的前提下,捕获并外部化其内部状态,并且可以在将来恢复到之前保存的状态。这种模式非常适合实现撤销/重做功能、保存及恢复状态等场景。

类图

备忘录模式

角色

备忘录模式主要包括以下三个角色:

  1. 发起人(Originator):负责创建一个包含其当前内部状态的备忘录,并能够使用该备忘录恢复其内部状态。
  2. 备忘录(Memento):负责存储发起人的内部状态,并防止其他对象访问备忘录。备忘录可以有两个接口,一个是窄接口(只能由负责人使用),另一个是宽接口(只能由发起人使用)。
  3. 负责人(Caretaker):负责保存好备忘录,但不能操作或检查备忘录的内容。

使用场景

  • 撤销/重做功能:如文本编辑器中的撤销操作。
  • 游戏状态保存与恢复:例如保存游戏进度,允许玩家返回之前的游戏状态。
  • 配置设置备份:在软件配置更改前后保存状态,以便用户可以恢复到之前的设置。
  • 事务管理:数据库操作中的事务回滚功能。

适用场景

功能比较复杂的,但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分时,Originator可以根据保存的Memento信息还原到前一状态。

优缺点

优点

  • 提供了状态恢复的能力,简化了状态管理的复杂度。
  • 改善了封装性,状态的存储由备忘录类管理,原发器类的内部细节不会暴露给其他对象。
  • 支持多次撤销操作,增强程序的灵活性和健壮性。

缺点

  • 如果状态复杂,可能会占用较大的内存空间。
  • 需要谨慎设计以避免备忘录对象包含过多不必要的信息,导致资源浪费。

示例

java
package com.justin.memento.textedit;

import java.util.ArrayList;
import java.util.List;

// 发起人
class TextEditor {
    private String text;

    public void setText(String text) {
        this.text = text;
    }

    public String getText() {
        return text;
    }

    public Memento save() {
        return new Memento(text);
    }

    public void restore(Memento memento) {
        this.text = memento.getText();
    }
   // 备忘录
    public static class Memento {
        private final String text;

        private Memento(String text) {
            this.text = text;
        }

        private String getText() {
            return text;
        }
    }
}

// 负责人
class Caretaker {
    private final List<TextEditor.Memento> mementoList = new ArrayList<>();

    public void addMemento(TextEditor.Memento memento) {
        mementoList.add(memento);
    }

    public TextEditor.Memento getMemento(int index) {
        return mementoList.get(index);
    }
}

// 测试
public class Test {
    public static void main(String[] args) {
        TextEditor editor = new TextEditor();
        Caretaker caretaker = new Caretaker();

        editor.setText("Version 1");
        caretaker.addMemento(editor.save());

        editor.setText("Version 2");
        caretaker.addMemento(editor.save());

        editor.setText("Version 3");

        System.out.println("Current Text: " + editor.getText());
        editor.restore(caretaker.getMemento(1));
        System.out.println("Restored to: " + editor.getText());
        editor.restore(caretaker.getMemento(0));
        System.out.println("Restored to: " + editor.getText());
    }
}

Released under the MIT License.