java23种设计模式-备忘录模式

server/2025/3/4 1:12:12/

备忘录模式(Memento Pattern)学习笔记


编程相关书籍分享:https://blog.csdn.net/weixin_47763579/article/details/145855793
DeepSeek使用技巧pdf资料分享:https://blog.csdn.net/weixin_47763579/article/details/145884039


1. 模式定义

行为型设计模式,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便后续恢复对象到原先保存的状态。

2. 适用场景

✅ 需要实现撤销/重做功能
✅ 需要保存对象历史快照
✅ 需要提供系统状态回滚机制
✅ 需要隔离对象状态存储细节
✅ 需要实现事务回滚操作

3. 模式结构

creates
Originator
-state: String
+createMemento() : Memento
+restore(m: Memento)
Memento
-state: String
+getState()
+setState()
Caretaker
-mementos: List
+addMemento(m: Memento)
+getMemento(index: int) : Memento

4. 核心角色

角色说明
Originator原发器:需要保存状态的对象
Memento备忘录:存储原发器内部状态的对象(通常不可修改)
Caretaker管理者:负责保存/恢复备忘录,但不能操作备忘录内容

5. 代码示例

5.1 文本编辑器撤销功能

// 备忘录类  
final class TextMemento {  private final String content;  public TextMemento(String content) {  this.content = content;  }  public String getContent() {  return content;  }  
}  // 原发器类  
class TextEditor {  private StringBuilder content = new StringBuilder();  public void append(String text) {  content.append(text);  }  public TextMemento save() {  return new TextMemento(content.toString());  }  public void restore(TextMemento memento) {  content = new StringBuilder(memento.getContent());  }  public void print() {  System.out.println("当前内容: " + content);  }  
}  // 管理者类  
class HistoryManager {  private final Stack<TextMemento> history = new Stack<>();  public void push(TextMemento memento) {  history.push(memento);  }  public TextMemento pop() {  return history.pop();  }  
}  // 客户端  
public class Client {  public static void main(String[] args) {  TextEditor editor = new TextEditor();  HistoryManager history = new HistoryManager();  editor.append("Hello");  history.push(editor.save());  editor.print();  editor.append(" World");  history.push(editor.save());  editor.print();  System.out.println("执行撤销操作:");  editor.restore(history.pop());  editor.print();  }  
}  
/* 输出:  
当前内容: Hello  
当前内容: Hello World  
执行撤销操作:  
当前内容: Hello */  

6. 模式变种

6.1 白箱 vs 黑箱实现

类型实现方式特点
白箱Memento公开状态访问方法违反封装原则,但实现简单
黑箱Memento使用内部类隐藏实现保持封装性,Java常用实现方式
// 黑箱实现示例  
class Originator {  private String state;  public IMemento save() {  return new Memento(state);  }  public void restore(IMemento m) {  this.state = ((Memento)m).getState();  }  // 内部类实现备忘录  private static class Memento implements IMemento {  private final String state;  private Memento(String state) {  this.state = state;  }  private String getState() {  return state;  }  }  
}  interface IMemento {} // 标记接口  

7. 优缺点分析

✔️ 优点

  • 保持对象封装边界
  • 简化原发器职责
  • 支持状态历史管理
  • 实现撤销/恢复机制

缺点

  • 消耗内存资源(需保存多个状态副本)
  • 频繁保存影响性能
  • 需要合理设计备忘录存储策略
  • 增加系统复杂度

8. 相关模式对比

模式目的关键区别
原型模式对象克隆关注对象复制,备忘录关注状态保存
命令模式操作封装命令模式可存储操作,备忘录存储状态
状态模式状态管理状态模式改变行为,备忘录保存状态

9. 实际应用案例

  • 文本/图形编辑器的撤销栈
  • 数据库事务回滚机制
  • 游戏存档/读档功能
  • 浏览器页面历史记录
  • IDE的本地历史功能
  • 金融系统的交易快照
  • Java序列化机制(Serializable)

10. 最佳实践建议

  1. 控制备忘录数量
// 使用最大历史记录限制  
class BoundedHistory {  private final Deque<Memento> stack = new ArrayDeque<>();  private final int maxSize;  public BoundedHistory(int maxSize) {  this.maxSize = maxSize;  }  public void push(Memento m) {  if (stack.size() >= maxSize) {  stack.removeFirst();  }  stack.addLast(m);  }  
}  
  1. 增量存储优化
// 仅存储变化量  
class DeltaMemento {  private final String delta;  private final long timestamp;  // ...  
}  
  1. 使用序列化实现深存储
// 通过序列化保存对象状态  
class SerializedMemento {  public static byte[] serialize(Object obj) throws IOException {  try (ByteArrayOutputStream bos = new ByteArrayOutputStream();  ObjectOutputStream oos = new ObjectOutputStream(bos)) {  oos.writeObject(obj);  return bos.toByteArray();  }  }  public static Object deserialize(byte[] data) throws Exception {  try (ByteArrayInputStream bis = new ByteArrayInputStream(data);  ObjectInputStream ois = new ObjectInputStream(bis)) {  return ois.readObject();  }  }  
}  
  1. 结合原型模式
class Originator implements Cloneable {  public Memento save() {  return new Memento(this.clone());  }  protected Originator clone() {  try {  return (Originator) super.clone();  } catch (CloneNotSupportedException e) {  throw new AssertionError();  }  }  
}  

🕰️ 设计原则体现

  1. 单一职责原则:状态管理职责分离到备忘录
  2. 开闭原则:新增备忘录类型无需修改原发器
  3. 封装性:保护对象内部状态不被直接访问

通过备忘录模式,可以实现灵活的状态管理机制,特别适合需要支持撤销/重做、事务回滚等功能的场景。该模式在编辑器、游戏开发、金融系统中应用广泛,是保护对象状态完整性的经典解决方案。


http://www.ppmy.cn/server/172211.html

相关文章

C++ 标准库容器的常用成员函数

目录 C 标准库容器简介 通用成员函数 1. 大小相关 size() empty() max_size() 2. 元素访问 operator[] at(size_t n) front() back() 3. 修改容器 push_back(const T& value) pop_back() clear() insert() erase() 4. 迭代器相关 begin() end() rbegi…

PHP函数与类:面向对象编程实践指南

PHP函数与类&#xff1a;面向对象编程实践指南 PHP的面向对象编程&#xff08;OOP&#xff09;能力使其成为构建可维护、可扩展Web应用的重要工具。本文从函数封装到类设计&#xff0c;系统讲解PHP面向对象编程的核心概念与实践技巧。 一、函数&#xff1a;代码复用的基本单元…

在 ASP.NET Core 中压缩并减少图像的文件大小

示例代码&#xff1a;https://download.csdn.net/download/hefeng_aspnet/90294127 在当今的数字时代&#xff0c;图像是 Web 应用程序和用户体验不可或缺的一部分。但是&#xff0c;处理大型图像文件可能会导致网页加载缓慢和更高的存储费用。为了解决这个问题&#xff0c;在…

第十四届蓝桥杯:DFS之飞机降落

这道题&#xff0c;由于它的数据范围是非常小的&#xff0c;我们可以采取暴力搜索的措施&#xff0c;把每种情况都枚举出来&#xff0c;如果有能行的情况就返回true 同时我们也要学会剪枝&#xff0c;如果已经确认飞机不能降落&#xff0c;就不要往下再展开了 #include <i…

第十五站:循环神经网络(RNN)与长短期记忆网络(LSTM)

1. 循环神经网络&#xff08;RNN&#xff09;概述 RNN 是一种非常适合处理序列数据的神经网络。与传统的前馈神经网络不同&#xff0c;RNN 具有一个 循环连接&#xff0c;它可以 记住 前一个时刻的信息&#xff0c;并将其传递到当前时刻。 RNN 的工作原理&#xff1a; 输入序…

设计模式Python版 观察者模式

文章目录 前言一、观察者模式二、观察者模式示例 前言 GOF设计模式分三大类&#xff1a; 创建型模式&#xff1a;关注对象的创建过程&#xff0c;包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。结构型模式&#xff1a;关注类和对象之间的组…

TCP 三次握手与四次挥手

TCP 三次握手与四次挥手知识总结 一、TCP 连接与断开的核心机制 1. 三次握手&#xff08;建立连接&#xff09; 目的&#xff1a; 建立客户端与服务端之间的双向传输通道&#xff0c;确保双方都能确认对方的接收和发送能力&#xff0c;为后续的数据传输奠定可靠基础。 流程…

【AIGC系列】3:Stable Diffusion模型原理介绍

AIGC系列博文&#xff1a; 【AIGC系列】1&#xff1a;自编码器&#xff08;AutoEncoder, AE&#xff09; 【AIGC系列】2&#xff1a;DALLE 2模型介绍&#xff08;内含扩散模型介绍&#xff09; 【AIGC系列】3&#xff1a;Stable Diffusion模型原理介绍 【AIGC系列】4&#xff1…