rokevin
移动
前端
语言
  • 基础

    • Linux
    • 实施
    • 版本构建
  • 应用

    • WEB服务器
    • 数据库
  • 资讯

    • 工具
    • 部署
开放平台
产品设计
  • 人工智能
  • 云计算
计算机
其它
GitHub
移动
前端
语言
  • 基础

    • Linux
    • 实施
    • 版本构建
  • 应用

    • WEB服务器
    • 数据库
  • 资讯

    • 工具
    • 部署
开放平台
产品设计
  • 人工智能
  • 云计算
计算机
其它
GitHub
  • 备忘录模式(Memento Pattern)

  • 一、定义
  • 二、意图
  • 三、结构
  • 四、类图(Mermaid 版)
  • 五、时序图(Mermaid 版)
  • 六、模式分析
    • 6.1 核心逻辑:封装与访问控制
    • 6.2 与原型模式的区别
  • 七、优点
  • 八、缺点
  • 九、适用环境
  • 十、模式应用
    • 10.1 基础场景
    • 10.2 框架与库
  • 十一、模式扩展
    • 11.1 增量备忘录(Incremental Memento)
    • 11.2 带版本的备忘录(Versioned Memento)
    • 11.3 备忘录管理器(Memento Manager)
  • 十二、Android 中的应用
    • 12.1 Activity 状态保存(onSaveInstanceState)
    • 12.2 ViewModel 与 SavedStateHandle
    • 12.3 自定义撤销功能(如富文本编辑器)
  • 十三、代码实现(Java 版)
    • 13.1 步骤 1:定义备忘录类(TextMemento)
    • 13.2 步骤 2:实现原发器(TextEditor)
    • 13.3 步骤 3:实现负责人(History)
    • 13.4 步骤 4:客户端测试
    • 13.5 运行结果
  • 十四、总结

备忘录模式(Memento Pattern)

备忘录模式是行为型设计模式的重要成员,其核心思想是在不破坏对象封装性的前提下,捕获对象的内部状态并保存,以便在未来某个时刻将对象恢复到之前的状态。这种模式广泛应用于需要 “撤销操作”“状态回滚” 或 “历史记录” 的场景,如文本编辑器的撤销功能、游戏存档、数据库事务回滚等。

一、定义

官方定义(参考《设计模式:可复用面向对象软件的基础》): Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later. (在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便日后将该对象恢复到原先保存的状态。)

通俗理解: 备忘录模式类似 “快照” 功能 —— 比如用手机拍照时,照片(备忘录)记录了当前场景(对象状态),日后可以通过照片回忆(恢复)当时的场景。关键是,拍照过程不会暴露场景的内部细节(如人物的隐私信息),即保持封装性。

  • Originator: 原始对象

  • Caretaker: 负责保存好备忘录

  • Menento: 备忘录,存储原始对象的的状态。备忘录实际上有两个接口,一个是提供给 Caretaker 的窄接口: 它只能将备忘录传递给其它对象;一个是提供给 Originator 的宽接口,允许它访问到先前状态所需的所有数据。理想情况是只允许 Originator 访问本备忘录的内部状态。

二、意图

备忘录模式的核心目标是解决以下问题:

  1. 状态捕获与恢复:允许在不暴露对象内部结构的前提下,保存对象的历史状态,以便需要时回滚到之前的状态;
  2. 封装保护:避免为了保存状态而将对象的私有属性暴露给外部(如不通过 getter 方法暴露私有字段);
  3. 状态管理解耦:将状态的保存、管理、恢复逻辑分离,原发器(Originator)专注于自身业务,负责人(Caretaker)专注于状态的管理。

三、结构

备忘录模式包含 3 个核心角色,复杂场景可扩展 “备忘录管理器” 或 “版本控制器”:

角色名称核心职责
原发器(Originator)1. 负责创建备忘录(Memento),记录自身当前的内部状态;2. 提供从备忘录恢复状态的方法;3. 包含自身的业务逻辑。
备忘录(Memento)1. 存储原发器的内部状态(通常包含原发器的私有属性副本);2. 对除原发器外的其他对象隐藏状态细节(通过访问权限控制)。
负责人(Caretaker)1. 负责保存备忘录对象(不直接操作备忘录的内容);2. 提供备忘录的存储(如列表、栈)和获取接口;3. 不了解备忘录的内部结构。

四、类图(Mermaid 版)

以 “文本编辑器的撤销功能” 为场景,用 Mermaid 类图展示备忘录模式的结构:

classDiagram
    direction TB

    %% 1. 原发器:文本编辑器,需要保存状态
    class TextEditor {
        - content: String  // 文本内容(需保存的状态)
        - cursorPosition: int  // 光标位置(需保存的状态)
        + type(text: String): void  // 输入文本(业务逻辑)
        + moveCursor(pos: int): void  // 移动光标(业务逻辑)
        + createMemento(): TextMemento  // 创建备忘录(保存当前状态)
        + restoreFromMemento(memento: TextMemento): void  // 从备忘录恢复
        + getContent(): String  // 辅助:获取内容(仅用于展示)
    }

    %% 2. 备忘录:存储文本编辑器的状态
    class TextMemento {
        - content: String  // 保存的文本内容
        - cursorPosition: int  // 保存的光标位置
        + TextMemento(content: String, cursorPos: int)  // 构造器(仅允许原发器调用)
        # getContent(): String  // 仅允许原发器访问(包私有或受保护)
        # getCursorPosition(): int  // 仅允许原发器访问
    }

    %% 3. 负责人:管理备忘录(撤销历史)
    class History {
        - mementos: Stack~TextMemento~  // 用栈存储备忘录(先进后出,符合撤销逻辑)
        + saveMemento(memento: TextMemento): void  // 保存备忘录
        + getLastMemento(): TextMemento  // 获取最近的备忘录(用于撤销)
        + getMementoCount(): int  // 辅助:获取历史记录数量
    }

    %% 角色关系
    TextEditor "1" --> "创建/恢复" TextMemento : 依赖 >
    TextEditor "1" --> "使用" History : 依赖 >
    History "1" --> "管理" TextMemento : 聚合 >

关键设计:

  • 备忘录(TextMemento)的状态获取方法(getContent()、getCursorPosition())设置为包私有或受保护,确保只有原发器(TextEditor)能访问,其他对象(如History)无法直接读取状态,保证封装性;
  • 负责人(History)仅负责存储备忘录,不参与状态的创建或恢复,符合单一职责原则。

五、时序图(Mermaid 版)

以 “文本编辑器输入→保存→继续输入→撤销” 为场景,展示备忘录模式的交互流程:

sequenceDiagram
    participant Client as 客户端(用户)
    participant Editor as 原发器(TextEditor)
    participant Memento as 备忘录(TextMemento)
    participant History as 负责人(History)

    %% 1. 初始化:创建编辑器和历史记录管理器
    Client->>Editor: 1. new TextEditor()
    Client->>History: 2. new History()

    %% 2. 第一次输入文本并保存状态
    Client->>Editor: 3. type("Hello ")  // 输入内容
    Client->>Editor: 4. moveCursor(6)  // 移动光标到末尾
    Client->>Editor: 5. createMemento()  // 创建备忘录
    Editor->>Memento: 6. new TextMemento("Hello ", 6)  // 备忘录保存当前状态
    Editor-->>Client: 7. 返回备忘录M1
    Client->>History: 8. saveMemento(M1)  // 保存备忘录到历史
    History-->>Client: 9. 保存成功

    %% 3. 继续输入并再次保存
    Client->>Editor: 10. type("World")  // 内容变为"Hello World"
    Client->>Editor: 11. moveCursor(11)  // 光标到末尾
    Client->>Editor: 12. createMemento()  // 创建备忘录
    Editor->>Memento: 13. new TextMemento("Hello World", 11)
    Editor-->>Client: 14. 返回备忘录M2
    Client->>History: 15. saveMemento(M2)
    History-->>Client: 16. 保存成功

    %% 4. 用户决定撤销(恢复到上一个状态)
    Client->>History: 17. getLastMemento()  // 获取最近的备忘录M2
    History-->>Client: 18. 返回M2(实际撤销通常取前一个,这里简化)
    Client->>Editor: 19. restoreFromMemento(M2)  // 恢复状态
    Editor->>Memento: 20. getContent() + getCursorPosition()  // 原发器读取备忘录
    Memento-->>Editor: 21. 返回"Hello World"和11
    Editor-->>Client: 22. 状态恢复完成(内容和光标已更新)

六、模式分析

6.1 核心逻辑:封装与访问控制

备忘录模式的关键是限制备忘录的访问权限,确保只有原发器能读写其状态:

  • 在 Java 中,通常将备忘录类声明为原发器的内部类,或与原发器放在同一包中,使用default(包私有)访问权限;
  • 备忘录的状态字段(如content)和获取方法(如getContent())对外部(如负责人)不可见,仅对原发器可见。
// 原发器与备忘录在同一包中,备忘录的方法为包私有
public class TextEditor {
    // 原发器的私有状态
    private String content;
    private int cursorPosition;
    
    // 创建备忘录(仅原发器能调用备忘录的构造器)
    public TextMemento createMemento() {
        return new TextMemento(content, cursorPosition);
    }
    
    // 从备忘录恢复(仅原发器能调用备忘录的get方法)
    public void restoreFromMemento(TextMemento memento) {
        this.content = memento.getContent();  // 包私有方法,可访问
        this.cursorPosition = memento.getCursorPosition();
    }
}

// 备忘录类(包私有访问权限,仅同一包可见)
class TextMemento {
    private String content;
    private int cursorPosition;
    
    // 构造器为包私有,仅原发器可创建
    TextMemento(String content, int cursorPosition) {
        this.content = content;
        this.cursorPosition = cursorPosition;
    }
    
    // 获取方法为包私有,仅原发器可访问
    String getContent() { return content; }
    int getCursorPosition() { return cursorPosition; }
}

6.2 与原型模式的区别

备忘录模式常与原型模式(Prototype)混淆(两者都涉及对象状态的复制),但核心意图不同:

对比维度备忘录模式(Memento)原型模式(Prototype)
核心意图保存对象的历史状态,支持回滚 / 撤销快速复制对象(创建与原对象相同状态的新对象)
状态使用用于恢复原对象的状态(同一对象)用于创建新对象(不同对象,状态相同)
封装性严格保护状态,仅原发器可访问通常需要暴露复制逻辑(如clone()方法)
典型场景文本编辑器撤销、游戏存档、事务回滚对象创建成本高(如数据库连接)、动态生成对象

七、优点

  1. 封装性好:备忘录模式将对象状态的捕获和恢复封装在原发器内部,外部(如负责人)无法直接访问对象的私有状态,符合封装原则;
  2. 简化原发器:原发器无需自行管理历史状态,只需创建和恢复备忘录,状态的存储和管理由负责人承担,降低原发器的复杂度;
  3. 支持多状态恢复:通过负责人管理多个备忘录,可实现多步撤销(如文本编辑器的 “撤销前 10 步”);
  4. 状态隔离:备忘录与原发器、负责人解耦,修改状态存储方式(如从内存到磁盘)只需调整备忘录和负责人,不影响原发器。

八、缺点

  1. 资源消耗大:如果对象状态复杂(如包含大量数据)或备忘录数量多(如 100 步撤销历史),会占用大量内存;
  2. 状态一致性风险:若原发器在创建备忘录后,未通过备忘录修改状态(如直接修改私有字段),会导致备忘录状态与实际状态不一致;
  3. 扩展性受限:新增状态字段时,需修改备忘录类的构造器和获取方法,可能违反开闭原则(需结合 Builder 模式缓解);
  4. 持久化复杂:若需将备忘录持久化到磁盘(如游戏存档),需处理序列化 / 反序列化,可能暴露状态细节。

九、适用环境

当系统满足以下条件时,适合使用备忘录模式:

  1. 需要保存和恢复对象的历史状态(如文本编辑器的撤销、Photoshop 的历史记录);
  2. 不希望暴露对象的内部状态(如避免通过 getter 方法暴露私有字段);
  3. 对象的状态变化频繁,且需要支持回滚(如数据库事务、表单填写);
  4. 状态的保存和恢复逻辑需要与对象本身解耦(如让专门的组件管理历史记录)。

十、模式应用

备忘录模式在软件开发中应用广泛,典型场景包括:

10.1 基础场景

  • 文本 / 图像编辑工具:如 Word 的撤销(Ctrl+Z)、Photoshop 的历史记录面板,通过备忘录保存每一步操作后的状态;
  • 游戏存档:玩家存档时,游戏(原发器)创建包含角色属性、地图状态的备忘录,存档文件(负责人)保存备忘录,读档时恢复;
  • 数据库事务:事务执行过程中,数据库(原发器)创建事务开始前的状态备忘录,若事务失败则通过备忘录回滚;
  • 表单填写:用户填写长表单(如注册信息)时,定期保存草稿(备忘录),防止意外关闭页面后数据丢失。

10.2 框架与库

  • Java Swing:JTextField等组件的undoableEditHappened事件,通过UndoManager(负责人)管理UndoableEdit(备忘录),支持撤销操作;
  • AndroidViewModel:通过onSaveInstanceState保存 UI 状态(如旋转屏幕时),本质是备忘录模式的简化(Bundle作为备忘录);
  • Git 版本控制:代码提交(commit)本质是创建备忘录,git checkout回滚版本即从备忘录恢复状态,Git 仓库作为负责人管理所有备忘录。

十一、模式扩展

11.1 增量备忘录(Incremental Memento)

对于状态变化较小的场景(如大型文档编辑),不保存完整状态,只记录与上一状态的差异(类似 Git 的增量提交),减少内存消耗:

// 增量备忘录:仅保存与上一状态的差异
class IncrementalMemento {
    private int startPos;  // 变化起始位置
    private String oldText;  // 被替换的旧文本
    private String newText;  // 新增的文本
    
    // 构造器:记录差异
    public IncrementalMemento(int startPos, String oldText, String newText) {
        this.startPos = startPos;
        this.oldText = oldText;
        this.newText = newText;
    }
    
    // 恢复逻辑:用旧文本替换新文本
    public void restore(TextEditor editor) {
        String content = editor.getContent();
        String restored = content.substring(0, startPos) 
            + oldText 
            + content.substring(startPos + newText.length());
        editor.setContent(restored);
    }
}

11.2 带版本的备忘录(Versioned Memento)

为备忘录添加版本号、时间戳等元数据,支持按版本或时间筛选恢复,适合需要审计的场景(如金融交易):

class VersionedMemento extends TextMemento {
    private String version;  // 版本号(如V1.0、V2.0)
    private LocalDateTime timestamp;  // 保存时间
    
    public VersionedMemento(String content, int cursorPos, String version) {
        super(content, cursorPos);
        this.version = version;
        this.timestamp = LocalDateTime.now();
    }
    
    // 获取元数据方法(对负责人可见)
    public String getVersion() { return version; }
    public LocalDateTime getTimestamp() { return timestamp; }
}

11.3 备忘录管理器(Memento Manager)

当存在多个原发器(如多个文档)时,新增备忘录管理器统一管理所有对象的备忘录,支持跨对象的状态恢复:

public class MementoManager {
    // 按对象ID和类型存储备忘录(键:"editor:123",值:备忘录列表)
    private Map<String, List<Memento>> mementoMap = new HashMap<>();
    
    // 保存指定对象的备忘录
    public void save(String objectId, String type, Memento memento) {
        String key = type + ":" + objectId;
        mementoMap.computeIfAbsent(key, k -> new ArrayList<>()).add(memento);
    }
    
    // 获取指定对象的历史备忘录
    public List<Memento> getHistory(String objectId, String type) {
        return mementoMap.getOrDefault(type + ":" + objectId, new ArrayList<>());
    }
}

十二、Android 中的应用

Android 框架和开发中,备忘录模式的思想被广泛应用,典型场景包括:

12.1 Activity 状态保存(onSaveInstanceState)

当 Activity 因配置变化(如旋转屏幕)或内存不足被销毁时,系统通过备忘录模式保存和恢复状态:

  • 原发器:Activity 或 Fragment,包含 UI 状态(如 EditText 内容、复选框状态);
  • 备忘录:Bundle 对象,存储键值对形式的状态数据(如putString("username", "xxx"));
  • 负责人:Android 系统,在 onSaveInstanceState 时保存 Bundle,在 onCreate 或 onRestoreInstanceState 时恢复。
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    // 保存EditText内容(创建备忘录)
    outState.putString("edit_text_content", editText.getText().toString());
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
        // 恢复EditText内容(从备忘录恢复)
        String content = savedInstanceState.getString("edit_text_content");
        editText.setText(content);
    }
}

12.2 ViewModel 与 SavedStateHandle

Android Jetpack 的 SavedStateHandle 是备忘录模式的增强实现,解决 ViewModel 在进程杀死后的数据丢失问题:

  • 原发器:ViewModel,包含业务数据(如用户信息、列表数据);
  • 备忘录:SavedStateHandle 内部的存储结构,支持跨进程保存数据;
  • 负责人:SavedStateRegistry,由系统管理 SavedStateHandle 的生命周期。
public class MyViewModel extends ViewModel {
    private final SavedStateHandle savedStateHandle;
    private static final String KEY_USER = "user_data";
    
    public MyViewModel(SavedStateHandle handle) {
        this.savedStateHandle = handle;
    }
    
    // 保存用户数据(创建备忘录)
    public void saveUser(User user) {
        savedStateHandle.set(KEY_USER, user);
    }
    
    // 恢复用户数据(从备忘录恢复)
    public User restoreUser() {
        return savedStateHandle.get(KEY_USER);
    }
}

12.3 自定义撤销功能(如富文本编辑器)

Android 应用开发中,实现自定义撤销功能时,通常直接使用备忘录模式:

  • 例如,一个笔记应用支持撤销输入,可通过 Stack 存储每一步的文本状态(备忘录),用户点击撤销时弹出最近的备忘录并恢复。

十三、代码实现(Java 版)

以 “文本编辑器的撤销功能” 为场景,完整实现备忘录模式:

13.1 步骤 1:定义备忘录类(TextMemento)

/**
 * 备忘录:存储文本编辑器的状态(内容和光标位置)
 * 访问权限:包私有(仅同一包中的TextEditor可访问其方法)
 */
class TextMemento {
    private final String content;       // 保存的文本内容
    private final int cursorPosition;   // 保存的光标位置

    // 构造器:仅允许同一包中的类调用(如TextEditor)
    TextMemento(String content, int cursorPosition) {
        this.content = content;
        this.cursorPosition = cursorPosition;
    }

    // 获取文本内容:仅允许同一包中的类调用
    String getContent() {
        return content;
    }

    // 获取光标位置:仅允许同一包中的类调用
    int getCursorPosition() {
        return cursorPosition;
    }
}

13.2 步骤 2:实现原发器(TextEditor)

/**
 * 原发器:文本编辑器,负责创建备忘录和从备忘录恢复状态
 */
public class TextEditor {
    private String content;       // 当前文本内容
    private int cursorPosition;   // 当前光标位置

    // 初始化:空内容,光标在0位置
    public TextEditor() {
        this.content = "";
        this.cursorPosition = 0;
    }

    // 输入文本(业务逻辑)
    public void type(String text) {
        // 在光标位置插入文本
        content = content.substring(0, cursorPosition) 
                + text 
                + content.substring(cursorPosition);
        // 移动光标到插入后的位置
        cursorPosition += text.length();
        System.out.println("输入后内容:" + content + ",光标位置:" + cursorPosition);
    }

    // 移动光标(业务逻辑)
    public void moveCursor(int position) {
        // 确保光标位置在有效范围内
        this.cursorPosition = Math.max(0, Math.min(position, content.length()));
        System.out.println("光标移动到:" + cursorPosition);
    }

    // 创建备忘录:保存当前状态
    public TextMemento createMemento() {
        System.out.println("创建备忘录,保存状态:" + content + "(光标:" + cursorPosition + ")");
        return new TextMemento(content, cursorPosition);
    }

    // 从备忘录恢复状态
    public void restoreFromMemento(TextMemento memento) {
        this.content = memento.getContent();  // 访问包私有方法
        this.cursorPosition = memento.getCursorPosition();
        System.out.println("恢复后内容:" + content + ",光标位置:" + cursorPosition);
    }

    // 辅助方法:获取当前内容(用于展示)
    public String getContent() {
        return content;
    }
}

13.3 步骤 3:实现负责人(History)

import java.util.Stack;

/**
 * 负责人:管理备忘录,提供保存和获取最近备忘录的功能
 */
public class History {
    // 用栈存储备忘录(先进后出,符合撤销逻辑:最近的操作先撤销)
    private final Stack<TextMemento> mementos = new Stack<>();

    // 保存备忘录
    public void saveMemento(TextMemento memento) {
        mementos.push(memento);
        System.out.println("保存备忘录,当前历史记录数:" + mementos.size());
    }

    // 获取最近的备忘录(用于撤销)
    public TextMemento getLastMemento() {
        if (mementos.isEmpty()) {
            throw new IllegalStateException("没有可恢复的历史记录");
        }
        return mementos.pop();
    }

    // 获取历史记录数量(辅助)
    public int getMementoCount() {
        return mementos.size();
    }
}

13.4 步骤 4:客户端测试

/**
 * 客户端:模拟用户使用文本编辑器的过程(输入→保存→继续输入→撤销)
 */
public class MementoPatternTest {
    public static void main(String[] args) {
        // 1. 创建原发器(文本编辑器)和负责人(历史记录)
        TextEditor editor = new TextEditor();
        History history = new History();

        // 2. 第一次操作:输入"Hello"并保存状态
        System.out.println("=== 第一次操作 ===");
        editor.type("Hello");
        editor.moveCursor(5);  // 移动光标到末尾
        history.saveMemento(editor.createMemento());  // 保存备忘录

        // 3. 第二次操作:输入" World"并保存状态
        System.out.println("\n=== 第二次操作 ===");
        editor.type(" World");
        editor.moveCursor(11);
        history.saveMemento(editor.createMemento());  // 保存备忘录

        // 4. 第三次操作:输入"!"(不保存)
        System.out.println("\n=== 第三次操作(不保存) ===");
        editor.type("!");
        System.out.println("当前内容:" + editor.getContent());  // 预期:Hello World!

        // 5. 撤销:恢复到上一次保存的状态(Hello World)
        System.out.println("\n=== 执行撤销 ===");
        editor.restoreFromMemento(history.getLastMemento());
        System.out.println("撤销后内容:" + editor.getContent());  // 预期:Hello World

        // 6. 再次撤销:恢复到第一次保存的状态(Hello)
        System.out.println("\n=== 再次执行撤销 ===");
        editor.restoreFromMemento(history.getLastMemento());
        System.out.println("再次撤销后内容:" + editor.getContent());  // 预期:Hello
    }
}

13.5 运行结果

=== 第一次操作 ===
输入后内容:Hello,光标位置:5
光标移动到:5
创建备忘录,保存状态:Hello(光标:5)
保存备忘录,当前历史记录数:1

=== 第二次操作 ===
输入后内容:Hello World,光标位置:11
光标移动到:11
创建备忘录,保存状态:Hello World(光标:11)
保存备忘录,当前历史记录数:2

=== 第三次操作(不保存) ===
输入后内容:Hello World!,光标位置:12
当前内容:Hello World!

=== 执行撤销 ===
恢复后内容:Hello World,光标位置:11
撤销后内容:Hello World

=== 再次执行撤销 ===
恢复后内容:Hello,光标位置:5
再次撤销后内容:Hello

十四、总结

备忘录模式是处理 “状态保存与恢复” 问题的最佳实践,其核心是在保护封装性的前提下,实现对象状态的安全存储与回滚。

  1. 核心价值:
    • 解决了 “状态捕获” 与 “封装性” 的矛盾,既允许保存对象状态,又不暴露其内部结构;
    • 将状态管理逻辑从业务对象中分离,符合单一职责原则,提高代码可维护性;
    • 为撤销操作、版本控制、事务回滚等场景提供了标准化解决方案。
  2. 使用建议:
    • 状态简单且变化少的场景(如 2-3 个字段),可直接用简单数据结构(如Map)替代备忘录类;
    • 状态复杂或数量多的场景,优先使用增量备忘录(只保存差异),减少资源消耗;
    • 需持久化备忘录时,注意序列化安全(避免敏感信息泄露),可结合加密机制;
    • 在 Android 开发中,优先使用系统提供的Bundle和SavedStateHandle,避免重复造轮子。
  3. 局限性: 备忘录模式并非银弹,对于状态频繁变化且内存敏感的场景(如实时数据处理),可能导致性能问题,需结合实际需求权衡使用。

总之,备忘录模式通过巧妙的封装设计,为对象的状态管理提供了灵活且安全的解决方案,是构建可靠、易用系统的重要工具

最近更新:: 2025/10/22 15:36
Contributors: 罗凯文, luokaiwen