首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >23种设计模式之备忘录模式

23种设计模式之备忘录模式

作者头像
紫风
发布2025-10-14 15:20:13
发布2025-10-14 15:20:13
1350
举报
备忘录模式 (Memento Pattern) 详细介绍

一、模式概述
  • 英文名称:Memento
  • 核心目标在不破坏对象封装性的前提下,捕获并保存对象的内部状态,以便后续恢复该状态。
  • 设计思想:通过备忘录对象隔离状态存储逻辑,实现状态的快照管理,支持撤销(Undo)、重做(Redo)或历史记录功能。

二、优缺点

优点

缺点

1. 状态封装:不暴露对象内部细节。

1. 内存占用高:频繁保存大对象状态可能导致内存溢出。

2. 简化原发器:状态管理职责分离。

2. 性能开销:频繁序列化/反序列化可能影响性能。

3. 支持状态回滚:灵活实现撤销/恢复。

3. 需管理生命周期:过期的备忘录需及时清理。


三、应用场景
  1. 文本编辑器:撤销(Undo)和重做(Redo)操作。
  2. 游戏存档:保存和恢复游戏进度。
  3. 事务回滚:数据库操作失败时恢复至之前状态。
  4. 对象状态快照:如 IDE 调试时的变量检查点。

四、代码实现与注释
1. 备忘录类(保存对象状态)
代码语言:javascript
复制
/**
 * 备忘录类:保存文本编辑器的状态(文本内容和光标位置)
 * 设为原发器的内部类,确保状态访问的封装性。
 */
public class TextEditor {
    // 原发器状态
    private String text;
    private int cursorPosition;

    public TextEditor() {
        this.text = "";
        this.cursorPosition = 0;
    }

    // 修改文本内容
    public void write(String newText) {
        this.text += newText;
        this.cursorPosition += newText.length();
    }

    // 创建备忘录(保存当前状态)
    public TextMemento save() {
        return new TextMemento(text, cursorPosition);
    }

    // 从备忘录恢复状态
    public void restore(TextMemento memento) {
        this.text = memento.getText();
        this.cursorPosition = memento.getCursorPosition();
    }

    // 打印当前状态
    public void printStatus() {
        System.out.printf("文本内容:%s\n光标位置:%d%n", text, cursorPosition);
    }

    /**
     * 备忘录内部类:封装原发器的状态
     */
    public static class TextMemento {
        private final String text;
        private final int cursorPosition;

        // 仅允许原发器创建备忘录
        private TextMemento(String text, int cursorPosition) {
            this.text = text;
            this.cursorPosition = cursorPosition;
        }

        // 仅允许原发器访问状态
        private String getText() {
            return text;
        }

        private int getCursorPosition() {
            return cursorPosition;
        }
    }
}
2. 负责人类(管理备忘录历史)
代码语言:javascript
复制
import java.util.Stack;

/**
 * 负责人类:管理备忘录的历史记录(使用栈结构支持撤销操作)
 */
public class History {
    private final Stack<TextEditor.TextMemento> mementos = new Stack<>();

    // 保存状态
    public void push(TextEditor.TextMemento memento) {
        mementos.push(memento);
    }

    // 撤销操作(恢复上一次状态)
    public TextEditor.TextMemento pop() {
        if (mementos.isEmpty()) {
            throw new IllegalStateException("无历史记录可撤销");
        }
        return mementos.pop();
    }
}
3. 客户端调用
代码语言:javascript
复制
public class Client {
    public static void main(String[] args) {
        TextEditor editor = new TextEditor();
        History history = new History();

        // 编辑文本并保存状态
        editor.write("Hello");
        history.push(editor.save());
        editor.printStatus();

        editor.write(" World!");
        history.push(editor.save());
        editor.printStatus();

        // 撤销到上一次状态
        System.out.println("\n===== 执行撤销 =====");
        editor.restore(history.pop());
        editor.printStatus();

        // 再次撤销(无历史记录)
        try {
            editor.restore(history.pop());
        } catch (IllegalStateException e) {
            System.out.println("错误:" + e.getMessage());
        }
    }
}
4. 输出结果
代码语言:javascript
复制
文本内容:Hello
光标位置:5
文本内容:Hello World!
光标位置:11

===== 执行撤销 =====
文本内容:Hello
光标位置:5
错误:无历史记录可撤销

五、模式结构图
代码语言:javascript
复制
+----------------+          +----------------+
|   Originator   | <>-----+ |   Memento      |
+----------------+          +----------------+
| +createMemento()          | -state         |
| +restore(Memento)         +----------------+
+----------------+                 ^
       |                           |
       |                           |
+----------------+          +----------------+
|   Caretaker    |          |                |
+----------------+          +----------------+
| -mementos:List |          |                |
| +saveMemento()  |          |                |
| +getMemento()   |          |                |
+----------------+          +----------------+

六、与其他模式的关系
  1. 命令模式:备忘录模式常与命令模式结合,实现命令的撤销/重做。
  2. 原型模式:备忘录可通过原型模式快速克隆对象状态。
  3. 状态模式:备忘录保存对象的历史状态,状态模式管理当前状态。

七、最佳实践
  1. 增量快照:仅保存变化的部分状态,减少内存占用。
  2. 序列化支持:将备忘录序列化存储至文件或数据库,实现持久化。
  3. 快照清理策略:如 LRU 算法自动清理旧快照,避免内存泄漏。

八、总结
  • 核心价值:解耦状态保存与恢复逻辑,保护对象内部状态的封装性。
  • 适用场景:需要撤销/重做、状态快照或事务回滚的系统。
  • 关键实现:原发器 + 备忘录(内部类) + 负责人(历史管理)。

备忘录模式在 Java 生态中的典型应用包括:

  • Swing 文本组件UndoManager 管理编辑操作的撤销/重做。
  • 游戏引擎:保存玩家位置、装备等状态用于读档。
  • 数据库事务:通过日志回滚未完成的事务。

掌握该模式能有效增强系统的可靠性和用户体验,尤其在需要状态回溯的场景中。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-04-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 备忘录模式 (Memento Pattern) 详细介绍
    • 一、模式概述
    • 二、优缺点
    • 三、应用场景
    • 四、代码实现与注释
      • 1. 备忘录类(保存对象状态)
      • 2. 负责人类(管理备忘录历史)
      • 3. 客户端调用
      • 4. 输出结果
    • 五、模式结构图
    • 六、与其他模式的关系
    • 七、最佳实践
    • 八、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档