Java设计模式再相识 (二十一)——备忘录模式

目录

  • 什么是备忘录模式?
  • 模式角色结构
  • 实际应用举例
  • 四、代码实现
    • 1. 发起人类 `Editor`
    • 2. 备忘录类 `EditorMemento`
    • 3. 管理者类 `Caretaker`
    • 4. 客户端调用
    • 输出结果
  • 小结
  • 优缺点
    • 优点
    • 缺点
  • 适用场景

在实际开发中,我们常常会遇到这样的需求:某个对象需要恢复到之前的某个状态。例如:

  • 文本编辑器的“撤销”功能
  • 游戏的“读档”操作
  • 表单的“重置”按钮
  • 配置管理中的“恢复默认设置”

这些场景的本质就是保存历史快照,以便在需要的时候回滚。

什么是备忘录模式?

备忘录模式(Memento Pattern) 是一种行为型设计模式,用于在不破坏封装性的前提下,捕获一个对象的内部状态,并在之后将该对象恢复到原先的状态。

简单来说,就是保存和恢复对象状态

模式角色结构

备忘录模式包含三个核心角色:

  • Originator(发起人):负责创建备忘录对象,并可以使用备忘录恢复自己的状态。
  • Memento(备忘录):用于存储发起人的内部状态,是一个只读对象,对外不暴露内部实现。
  • Caretaker(管理者):负责保存和管理备忘录,但不能修改备忘录的内容。

实际应用举例

我们通过一个“文本编辑器”示例来理解备忘录模式:用户每输入一段内容,我们就保存一个快照;当用户点击“撤销”时,恢复到上一个快照。

四、代码实现

1. 发起人类 Editor

public class Editor {
    private String text;

    public void write(String input) {
        this.text = input;
        System.out.println("输入内容:" + text);
    }

    public String getText() {
        return text;
    }

    // 创建备忘录
    public EditorMemento save() {
        return new EditorMemento(text);
    }

    // 恢复备忘录
    public void restore(EditorMemento memento) {
        this.text = memento.getText();
        System.out.println("恢复内容:" + text);
    }
}

2. 备忘录类 EditorMemento

public class EditorMemento {
    private final String text;

    public EditorMemento(String text) {
        this.text = text;
    }

    public String getText() {
        return text;
    }
}

3. 管理者类 Caretaker

import java.util.Stack;

public class Caretaker {
    private Stack<EditorMemento> history = new Stack<>();

    public void save(EditorMemento memento) {
        history.push(memento);
    }

    public EditorMemento undo() {
        if (!history.isEmpty()) {
            return history.pop();
        }
        return null;
    }
}

4. 客户端调用

public class Main {
    public static void main(String[] args) {
        Editor editor = new Editor();
        Caretaker caretaker = new Caretaker();

        editor.write("第一次输入");
        caretaker.save(editor.save()); // 保存第一次状态

        editor.write("第二次输入");
        caretaker.save(editor.save()); // 保存第二次状态

        editor.write("第三次输入"); // 没保存

        System.out.println("--- 撤销一次 ---");
        editor.restore(caretaker.undo());

        System.out.println("--- 再次撤销 ---");
        editor.restore(caretaker.undo());
    }
}

输出结果

输入内容:第一次输入
输入内容:第二次输入
输入内容:第三次输入
--- 撤销一次 ---
恢复内容:第二次输入
--- 再次撤销 ---
恢复内容:第一次输入

小结

备忘录模式非常适合用于处理需要状态回退的场景,尤其是“撤销 / 重做”、“状态快照”、“历史版本”等功能。它把状态管理封装得非常好,不需要暴露内部结构,也不会破坏对象封装性。

优缺点

优点

  • 满足开闭原则,不影响原类封装
  • 可以提供多个历史状态记录,方便回退。
  • 适用于需要“撤销、恢复”功能的系统。

缺点

  • 如果保存的状态较多或状态数据过大,会占用较多内存。
  • 有时候可能需要定义多个备忘录类来保存不同的状态内容,增加了类的数量。

适用场景

  • 编辑器中的撤销 / 重做
  • 游戏存档和读档功能
  • 表单重置和回退操作
  • 配置恢复默认值
Java设计模式行为型模式
2025 © Yeliheng的技术小站 版权所有