【设计模式】行为型-备忘录模式

文章目录


前言

开发中经常需要撤销、回滚、快照、恢复 功能:比如编辑器 Ctrl+Z、游戏存档、订单回滚、配置恢复。如果直接把对象内部状态暴露出去,会破坏封装;如果自己管理备份,代码又会臃肿。备忘录模式 就是专门解决状态备份与恢复、且不破坏封装的行为型设计模式。


一、概念

备忘录模式(Memento Pattern) 是一种行为型设计模式 ,核心思想:
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后可以将该对象恢复到原先保存的状态。

简单理解:

  • 原发器(Originator):要备份的对象(如编辑器)
  • 备忘录(Memento):存储状态的快照(不可篡改)
  • 看管人(Caretaker):只负责保存快照,不看内容

一句话总结:
存档 → 快照 → 读档,且快照内容谁都不能改。


二、核心结构

  1. Originator(原发器)
    创建备忘录、从备忘录恢复状态。
  2. Memento(备忘录)
    存储内部状态,只允许原发器读取。
  3. Caretaker(看管人)
    持有备忘录,不能访问/修改内容,只负责存和取。

三、Java 代码实现(编辑器撤销)

场景:编辑器内容备份与恢复(Ctrl+Z)

1. 备忘录(快照)

java 复制代码
// 备忘录:存储状态,不可修改
public class EditorMemento {
    private final String content;

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

    // 只给原发器用
    public String getContent() {
        return content;
    }
}

2. 原发器(编辑器)

java 复制代码
// 原发器:创建快照、恢复快照
public class Editor {
    private String content;

    public void setContent(String content) {
        this.content = content;
    }

    public String getContent() {
        return content;
    }

    // 创建备忘录(存档)
    public EditorMemento createMemento() {
        return new EditorMemento(content);
    }

    // 从备忘录恢复(读档)
    public void restoreFromMemento(EditorMemento memento) {
        this.content = memento.getContent();
    }
}

3. 看管人(历史记录)

java 复制代码
// 看管人:只保存备忘录,不看内容
public class History {
    private EditorMemento memento;

    public void setMemento(EditorMemento memento) {
        this.memento = memento;
    }

    public EditorMemento getMemento() {
        return memento;
    }
}

4. 客户端测试

java 复制代码
public class Client {
    public static void main(String[] args) {
        Editor editor = new Editor();
        History history = new History();

        // 编辑内容
        editor.setContent("第1版内容");
        // 存档
        history.setMemento(editor.createMemento());

        // 修改
        editor.setContent("第2版修改内容");
        System.out.println("当前:" + editor.getContent());

        // 撤销(恢复)
        editor.restoreFromMemento(history.getMemento());
        System.out.println("撤销后:" + editor.getContent());
    }
}

输出:

复制代码
当前:第2版修改内容
撤销后:第1版内容

四、严格封装(最佳实践)

为了防止外部篡改备忘录,通常做法:

  • Memento 设为私有内部类
  • 只暴露窄接口(空接口)给 Caretaker
  • 只有 Originator 能访问宽接口

这样绝对安全,不会破坏封装。


五、优缺点

优点

  1. 不破坏封装实现备份/恢复
  2. 职责分离:原发器管业务,看管人管存储
  3. 可实现撤销、回滚、快照、重做
  4. 易于实现多版本管理

缺点

  1. 频繁备份会消耗大量内存
  2. 状态复杂时,备忘录管理成本高
  3. 某些语言难以保证备忘录不可篡改

六、应用场景

  • 编辑器撤销(Ctrl+Z)
  • 游戏存档/读档
  • 事务回滚、订单取消
  • 配置恢复、系统快照
  • 虚拟机 checkpoint、容器快照

经典应用:

  • IDEA/Eclipse 撤销重做
  • Git commit(可理解为备忘录)
  • Spring StateMachine 状态保存
  • database transaction rollback

七、备忘录 VS 命令 VS 状态

  • 备忘录:保存/恢复状态
  • 命令:封装行为,支持撤销
  • 状态:状态决定行为

八、总结

  1. 备忘录模式 = 快照 + 存档 + 恢复
  2. 核心:不破坏封装,安全备份状态
  3. 结构:Originator + Memento + Caretaker
  4. 是实现撤销、回滚、存档最标准的设计模式
相关推荐
光影少年2 小时前
实现发布订阅模式
前端·javascript·设计模式
无籽西瓜a3 小时前
【西瓜带你学设计模式 | 第十一期 - 模板方法模式】模板方法模式 —— 流程骨架与钩子实现、优缺点与适用场景
java·后端·设计模式·软件工程·模板方法模式
砍光二叉树16 小时前
【设计模式】行为型-中介者模式
设计模式·中介者模式
sanzk20 小时前
工厂方法模式
设计模式
大数据新鸟1 天前
设计模式详解——外观模式
设计模式·外观模式
缘友一世1 天前
PentestGPT V2源码研究之工具层设计模式
设计模式
yinghuoAI20261 天前
电商视觉进入“无人区”:萤火AI如何用三把“手术刀”重构设计 workflow
设计模式·新媒体运营·产品运营·流量运营·用户运营·内容运营·设计规范
sg_knight1 天前
设计模式实战:观察者模式(Observer)
python·观察者模式·设计模式
Yu_Lijing1 天前
基于C++的《Head First设计模式》笔记——MVC模式
c++·笔记·设计模式