当前位置: 首页 > news >正文

设计模式:Memento 模式详解

Memento 模式详解

Memento(备忘录)模式是一种行为型设计模式,用于在不破坏封装性的前提下,捕获并外部化一个对象的内部状态,以便在之后能够将该对象恢复到原先保存的状态。它广泛应用于需要实现撤销(Undo)、回滚、历史记录、快照机制等场景,如文本编辑器、图形设计工具、游戏存档系统、事务管理与配置回退。该模式通过将状态的保存与恢复职责分离,保护了对象的封装性,避免了将内部状态暴露给外部调用者,是构建可维护、可恢复系统的重要技术手段。

一、Memento 模式的结构与核心角色

Memento 模式源于对“状态保存-恢复”问题的抽象,属于 GoF(Gang of Four)23 种经典设计模式之一。其核心思想是引入一个中间对象——备忘录(Memento),作为原发器(Originator)状态的容器,并由负责人(Caretaker)管理备忘录的生命周期。该模式涉及三个关键角色:

  • Originator(原发器):需要被保存和恢复状态的对象,如文档、游戏角色或配置管理器。
  • Memento(备忘录):存储 Originator 内部状态的快照对象,通常只允许 Originator 访问其内容。
  • Caretaker(负责人):负责保存和管理 Memento 对象,但不能访问其内部状态。

这种职责分离确保了 Originator 的封装性不被破坏,同时实现了状态的历史管理。其类结构关系如下图所示:

creates and uses
stores and retrieves
Originator
-state: String
+setState(state)
+getState()
+saveStateToMemento()
+getStateFromMemento(Memento)
Memento
-state: String
+getState()
Caretaker
-mementoList: List<Memento>
+add(Memento)
+get(int)

Originator 创建 Memento 来保存当前状态,Caretaker 负责存储这些 Memento(如栈或列表),并在需要时交还给 Originator 进行恢复。

二、Memento 模式详解

2.1 Originator(原发器)

Originator 是系统中需要支持状态回退的核心对象。它包含业务数据和逻辑,例如一个文本编辑器中的文档内容、一个游戏角色的生命值与位置等。Originator 提供 saveStateToMemento() 方法,用于创建一个包含当前状态的 Memento 对象;同时提供 getStateFromMemento(Memento) 方法,用于从 Memento 中恢复状态。关键在于,Memento 的构造函数通常由 Originator 调用,并传入其私有状态,从而保证状态封装性不被外部破坏。Originator 可以在状态变化前主动保存快照,或响应外部请求进行恢复。

2.2 Memento(备忘录)

Memento 是一个轻量级的数据载体,其主要职责是安全地保存 Originator 的内部状态。它通常只提供一个读取状态的方法(如 getState()),而不允许外部修改。在强封装要求下,Memento 的状态字段为私有,且仅 Originator 可访问——这可通过语言特性实现,如 Java 中的包级私有或友元类机制。Memento 本身不包含任何业务逻辑,仅作为状态的“容器”。它可以支持序列化以便持久化存储,或用于网络传输实现远程状态恢复。由于 Memento 可能频繁创建,需注意内存占用,必要时可结合对象池或压缩机制优化。

2.3 Caretaker(负责人)

Caretaker 负责管理 Memento 的生命周期,但它不能也不应访问 Memento 中的状态内容。它通常将 Memento 存储在集合中,如栈(用于实现撤销/重做)、队列(用于历史记录)或列表(用于快照管理)。Caretaker 根据操作序列调用 Originator 的保存方法获取 Memento 并存储;在用户请求“撤销”时,从集合中取出最近的 Memento 并交还给 Originator 进行恢复。Caretaker 与 Originator 解耦,使得状态管理逻辑独立于业务逻辑,提升了系统的模块化程度。例如,一个通用的“命令历史管理器”可作为 Caretaker,服务于多个不同类型的 Originator。

三、总结

以下表格对比了 Memento 模式中三个角色的职责与访问权限:

角色职责是否可访问 Memento 状态典型实现方式
Originator创建、恢复状态是(唯一可读取者)提供 save/get 方法
Memento存储状态快照自身可读,外部不可写私有状态 + 只读接口
Caretaker管理 Memento 生命周期否(仅持有引用)栈、列表、队列存储

Memento 模式通过这种严格的访问控制,实现了封装性与可恢复性的统一。它适用于任何需要状态快照的场景,尤其在交互式系统中价值显著。

架构师洞见:
Memento 模式不仅是实现撤销功能的技术工具,更是构建可观察、可回滚、可调试系统的架构基础。在微服务与事件溯源(Event Sourcing)架构中,其思想被进一步扩展:每个状态变更作为事件记录,系统可通过重放事件流恢复任意历史状态——这本质上是 Memento 模式的时序化与持久化演进。现代系统中,Memento 常与 Command 模式结合,形成“命令-备忘录”对,支持多级撤销与事务回滚。未来,随着 AI 驱动的自动回退与异常修复需求增长,Memento 模式将向智能化、轻量化与分布式快照方向发展。架构师应重视状态管理的设计,避免将“临时状态”与“持久状态”混杂,确保系统具备良好的可恢复性与运维能力。

http://www.dtcms.com/a/299470.html

相关文章:

  • 简单实现支付密码的页面及输入效果
  • 面条式代码(Spaghetti Code)
  • Java高级之基于Java Attach与Byte-Buddy实现SQL语句增强
  • JWT安全机制与最佳实践详解
  • Linux 系统调用详解:操作文件的常用系统调用
  • Vulnhub jangow-01-1.0.1靶机渗透攻略详解
  • 自定义定时任务功能详解
  • MySQL 表的约束
  • 【面板数据】中国A股上市公司制造业智能制造数据集(1992-2024年)
  • 基于图神经网络的星间路由与计算卸载强化学习算法设计与实现
  • java实现一个方法,isTure则程序继续往下,为false则return的链式写法
  • 零基础学习性能测试第三章:jmeter线程组组合
  • LeetCode|Day26|191. 位 1 的个数|Python刷题笔记
  • Java学习|黑马笔记|Day23】网络编程、反射、动态代理
  • AI+预测3D新模型百十个定位预测+胆码预测+去和尾2025年7月26日第150弹
  • 在Power Automate Desktop中执行PowerShell获取SharePoint online某个文件夹的用户权限列表
  • SAP ABAP的数据通过调用泛微Restful API同步数据到OA建模表
  • 学习日志19 python
  • pytest中的rerunfailures的插件(失败重试)
  • 在 Scintilla 中为 Squirrel 语言设置语法解析器的方法
  • 【Kubernetes】使用StatefulSet进行的资源调度,扩缩容,更改配置到版本回滚,三种配置更新方式
  • c#中让图片显示清晰
  • 三、平衡桥电路
  • 060_泛型擦除与边界限定
  • MySQL数据库SQL语句进阶篇——连接查询与子查询详解
  • Traffic Lights set的使用
  • CSS变量与Houdini自定义属性:解锁样式编程新维度
  • Go 语言函数设计原则:避免修改传入参数
  • MCU中的GPIO(通用输入/输出)是什么?
  • [Qt]QString隐式拷贝