• 设计模式之备忘录模式


    问题背景

    在开发一个文本编辑器应用时,实现撤销(Undo)和重做(Redo)功能是一项常见需求。用户在编辑文本时可能会进行错误操作,需要一个机制可以回退到之前的状态。传统的方法可能需要复制整个编辑状态,这既不高效也不易于管理。备忘录模式提供了一种解决方案,允许保存和恢复对象的内部状态,同时不违反对象的封装性。

    问题分析

    1. 问题背景和需求:
      文本编辑器的用户在编辑过程中可能会犯错误,或者希望查看之前的编辑状态。提供一种有效且用户友好的方法来管理这些状态非常重要。

    2. 备忘录模式的适用性:
      备忘录模式通过三个主要对象来实现状态的保存和恢复:原发器(Originator)、备忘录(Memento)和管理者(Caretaker)。原发器负责生成备忘录对象以保存当前的状态,并可以使用备忘录对象恢复到之前的状态。管理者则负责保存备忘录,但它不修改备忘录或检查其内容。

    3. 设计类结构和接口:

    • 原发器(Originator):负责创建备忘录以保存其当前状态,并能使用备忘录恢复到先前的状态。
    • 备忘录(Memento):作为一个纯粹的数据结构,存储原发器的状态,对除原发器外的其他对象隐藏其实现细节。
    • 管理者(Caretaker):持有备忘录,但除了获取和保存备忘录外不进行任何操作。

    代码部分

    定义原发器、备忘录和管理者:

    #include 
    #include 
    
    // 备忘录类
    class Memento {
        friend class Originator;
        std::string state;
        Memento(const std::string& s) : state(s) {}
    public:
        std::string getState() const { return state; }
    };
    
    // 原发器类
    class Originator {
        std::string state;
    public:
        void setState(const std::string& s) {
            state = s;
            std::cout << "State set to: " << state << std::endl;
        }
    
        Memento createMemento() {
            return Memento(state);
        }
    
        void restoreState(const Memento& memento) {
            state = memento.getState();
            std::cout << "State restored to: " << state << std::endl;
        }
    };
    
    // 管理者类
    class Caretaker {
        std::vector<Memento> mementos;
    public:
        void saveMemento(const Memento& m) {
            mementos.push_back(m);
        }
    
        Memento getMemento(int index) {
            if (index < 0 || index >= mementos.size()) {
                throw std::runtime_error("Invalid index");
            }
            return mementos[index];
        }
    };
    
    int main() {
        Originator editor;      // 创建原发器对象,代表文本编辑器
        Caretaker caretaker;    // 创建管理者对象,负责管理备忘录
    
        // 用户在编辑器中的操作
        editor.setState("State1: Hello");
        caretaker.saveMemento(editor.createMemento()); // 保存状态1
    
        editor.setState("State2: Hello World");
        caretaker.saveMemento(editor.createMemento()); // 保存状态2
    
        // 撤销到先前状态
        editor.restoreState(caretaker.getMemento(0));  // 恢复到状态1
    
        // 可能的输出展示
        editor.setState("State3: Hello World!!!");
        caretaker.saveMemento(editor.createMemento()); // 保存新状态
    
        // 重做到更新后的状态
        editor.restoreState(caretaker.getMemento(2));  // 恢复到状态3
    
        return 0;
    }
    

    代码分析和总结

    备忘录模式的实现展示了如何有效地管理文本编辑器的状态历史,以支持撤销和重做操作。

    1. 备忘录模式的组件互动:
    • 原发器(Originator)负责创建包含其当前状态的备忘录,并可以使用备忘录恢复到之前的状态。
    • 备忘录(Memento)封装了原发器的内部状态,从而使得该状态可以独立于原发器外部保存和恢复。
    • 管理者(Caretaker)管理备忘录的存储,确保备忘录的保存和获取按照需求进行,但它不查看或操作备忘录的内容。
    1. 备忘录模式的优势:
    • 封装性:备忘录模式很好地封装了状态的保存和恢复过程,原发器的内部状态对其他对象保持私有,从而不会破坏原发器对象的封装。
    • 易于管理:通过管理者类,备忘录的管理变得集中和一致,使得实现撤销和重做功能变得更加直观和易于维护。
    1. 潜在的不足:
    • 资源消耗:如果原发器的状态大或状态保存频繁,备忘录可能会消耗大量内存。
    • 复杂性管理:在具有复杂状态的应用中,确保备忘录正确捕获和恢复所有必要的状态细节可能变得挑战。

    总的来说,备忘录模式为管理对象的状态提供了一种有效的方法,尤其适用于需要撤销和重做操作的应用。它通过分离状态存储和对象行为,增强了系统的可维护性和扩展性。

  • 相关阅读:
    Linux·【ftp】【nfs】【ssh】服务器搭建
    LeetCode_单调栈_中等_907.子数组的最小值之和
    DRF请求与响应
    vLLM-prefix浅析(System Prompt,大模型推理加速)
    Operator Bundle简介
    Kotlin 中的 inline 和nonline 和crossinline
    【极简python】第十章 模块的定义与使用
    深圳企业制作宣传片群体定位的重要性
    AI 边缘计算平台 - 爱芯元智 AX620A 爱芯派开箱
    客户需求调研的三个实用工具
  • 原文地址:https://blog.csdn.net/karl2000/article/details/138557027