备忘录设计模式

备忘录模式(Memento Pattern)是一种行为设计模式,用于捕获对象的内部状态并在需要时恢复该状态,同时不破坏对象的封装性。它适用于需要实现撤销/重做、历史记录或状态快照的场景。

核心组件
  1. Originator(原发器)

    • 需要保存状态的对象

    • 提供创建备忘录和恢复状态的方法

    • 示例代码:

      java 复制代码
      public class TextEditor {
          private String content;
          
          public void write(String text) {
              this.content = text;
          }
          
          // 创建备忘录
          public TextMemento save() {
              return new TextMemento(content);
          }
          
          // 从备忘录恢复
          public void restore(TextMemento memento) {
              this.content = memento.getSavedContent();
          }
      }
  2. Memento(备忘录)

    • 存储 Originator 的内部状态

    • 通常设计为不可变对象

    • 示例代码:

      java 复制代码
      public final class TextMemento {
          private final String content;
          
          public TextMemento(String content) {
              this.content = content;
          }
          
          // 仅允许原发器访问
          String getSavedContent() {
              return content;
          }
      }
  3. Caretaker(管理者)

    • 负责保存和管理备忘录

    • 不能修改备忘录内容

    • 示例代码:

      java 复制代码
      import java.util.Stack;
      
      public class History {
          private final Stack<TextMemento> states = new Stack<>();
          
          public void saveState(TextMemento state) {
              states.push(state);
          }
          
          public TextMemento getLastState() {
              return states.pop();
          }
      }
工作流程
graph LR A[Originator] -- 创建 --> B[Memento] B -- 存储 --> C[Caretaker] C -- 提供 --> A A -- 恢复状态 --> B
关键特性
  1. 封装保护

    • Memento 通过私有访问控制保护状态
    • Caretaker 只能存储备忘录,不能修改内容
  2. 状态管理

    • 支持多级撤销:使用栈结构存储历史状态
    • 状态隔离:每个备忘录独立存储对象快照
  3. 内存优化

    • 增量存储:仅保存变化部分
    • 懒加载:需要时再生成备忘录
适用场景
  • 需要实现撤销/重做功能(如文本编辑器)
  • 需要保存对象历史状态(如游戏存档)
  • 需要隔离状态生成和存储逻辑
优缺点分析

优点

  • 保持对象封装边界
  • 简化原发器职责(SRP原则)
  • 支持多状态管理

缺点

  • 可能增加内存消耗
  • Caretaker 需维护生命周期
  • 频繁保存可能影响性能
扩展实现
java 复制代码
// 客户端使用示例
public class Client {
    public static void main(String[] args) {
        TextEditor editor = new TextEditor();
        History history = new History();
        
        editor.write("First draft");
        history.saveState(editor.save());  // 保存状态1
        
        editor.write("Revised content");
        history.saveState(editor.save());  // 保存状态2
        
        editor.restore(history.getLastState()); // 撤销到状态1
    }
}

设计建议

  1. 对大型对象使用增量备忘录
  2. 通过接口约束备忘录访问权限
  3. 结合原型模式优化状态克隆性能
  4. 使用对象池管理频繁创建的备忘录
相关推荐
不会C语言的男孩30 分钟前
C++ Primer Plus 第8章:函数探幽
开发语言·c++
方也_arkling8 小时前
【Java-Day08】static / final / 枚举
java·开发语言
橙淮8 小时前
Spring Bean作用域与生命周期全解析
java·spring
风吹夏回8 小时前
Python 全局异常处理:从“满屏 try-except”到优雅兜底
开发语言·python
Chengbei119 小时前
一站式源码安全检测工具、云安全 / APP / 小程序源码敏感信息递归多层目录扫描AK、JWT、手机号、身份证等敏感信息
java·开发语言·安全·web安全·网络安全·系统安全·安全架构
llz_1129 小时前
web-第一次课后作业
java·开发语言·idea
小熊Coding9 小时前
Python爬取当当网二手图书项目实战!
开发语言·爬虫·python·beautifulsoup·requests·二手图书
秋99 小时前
Java项目运行5天左右自动宕机:系统性定位与解决方案
java·开发语言·python
小江的记录本9 小时前
【JVM虚拟机】垃圾回收GC:垃圾收集器:CMS:核心原理、回收流程、优缺点、废弃原因(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·spring·面试·maven
xiaoshuaishuai89 小时前
C# 内存管理与资源泄漏
开发语言·c#