C++ 备忘录模式详解

备忘录模式(Memento Pattern)是一种行为设计模式,它允许在不破坏封装性的前提下,捕获并外部化 一个对象的内部状态,以便以后可以恢复到这个状态。

核心概念

设计原则

备忘录模式遵循以下设计原则:

  1. 封装性原则:不暴露对象内部实现细节

  2. 单一职责原则:将状态保存与恢复职责分离

  3. 开闭原则:可以引入新的备忘录类型而不修改原始类

主要优点

  1. 状态保存:可以轻松实现撤销/恢复功能

  2. 封装保护:不破坏对象的封装性

  3. 简化原发器:将状态管理职责分离

  4. 时间快照:支持创建多个时间点的状态快照

模式结构

主要组件

  1. Originator(原发器)

    • 需要保存状态的对象

    • 创建备忘录以保存当前状态

    • 使用备忘录恢复状态

  2. Memento(备忘录)

    • 存储原发器的内部状态

    • 防止原发器以外的对象访问

  3. Caretaker(管理者)

    • 负责保存备忘录

    • 不操作或检查备忘录内容

完整代码示例

复制代码
#include <iostream>
#include <string>
#include <vector>
#include <memory>

// ==================== 备忘录类 ====================
class EditorMemento {
    // 备忘录保存的状态
    std::string content_;
    
    // 只允许Editor类创建和访问备忘录
    friend class Editor;
    
    // 私有构造函数,确保只有Editor可以创建备忘录
    explicit EditorMemento(const std::string& content) 
        : content_(content) {}
    
public:
    // Editor可以通过此方法获取保存的状态
    std::string getContent() const { return content_; }
};

// ==================== 原发器类 ====================
class Editor {
    std::string content_;
    
public:
    void type(const std::string& words) {
        content_ += words;
    }
    
    std::string getContent() const {
        return content_;
    }
    
    // 创建备忘录:保存当前状态
    std::unique_ptr<EditorMemento> save() {
        return std::make_unique<EditorMemento>(content_);
    }
    
    // 恢复状态:从备忘录恢复
    void restore(const EditorMemento* memento) {
        content_ = memento->getContent();
    }
};

// ==================== 管理者类 ====================
class History {
    std::vector<std::unique_ptr<EditorMemento>> mementos_;
    Editor* editor_;
    
public:
    explicit History(Editor* editor) : editor_(editor) {}
    
    void backup() {
        std::cout << "保存状态..." << std::endl;
        mementos_.push_back(editor_->save());
    }
    
    void undo() {
        if (mementos_.empty()) return;
        
        auto memento = std::move(mementos_.back());
        mementos_.pop_back();
        
        std::cout << "恢复状态..." << std::endl;
        editor_->restore(memento.get());
    }
    
    void showHistory() const {
        std::cout << "\n历史记录:" << std::endl;
        for (size_t i = 0; i < mementos_.size(); ++i) {
            std::cout << i+1 << ". " 
                      << mementos_[i]->getContent().substr(0, 10) 
                      << (mementos_[i]->getContent().length() > 10 ? "..." : "")
                      << std::endl;
        }
    }
};

// ==================== 客户端代码 ====================
int main() {
    std::cout << "=== 文本编辑器撤销功能演示 ===" << std::endl;
    
    Editor editor;
    History history(&editor);
    
    // 编辑并保存状态
    editor.type("Hello, ");
    history.backup();
    
    editor.type("world! ");
    history.backup();
    
    editor.type("This is a memento pattern example.");
    std::cout << "\n当前内容: " << editor.getContent() << std::endl;
    
    // 显示历史
    history.showHistory();
    
    // 撤销一次
    history.undo();
    std::cout << "\n撤销后内容: " << editor.getContent() << std::endl;
    
    // 再撤销一次
    history.undo();
    std::cout << "再撤销后内容: " << editor.getContent() << std::endl;
    
    return 0;
}

模式变体

1. 增量备忘录

复制代码
class IncrementalMemento {
    std::string change_; // 只保存变化部分
    friend class Editor;
    explicit IncrementalMemento(const std::string& change) : change_(change) {}
};

class Editor {
    std::string content_;
    std::vector<std::unique_ptr<IncrementalMemento>> changes_;
    
public:
    void type(const std::string& words) {
        changes_.push_back(std::make_unique<IncrementalMemento>(words));
        content_ += words;
    }
    
    void undo() {
        if (changes_.empty()) return;
        
        auto lastChange = changes_.back()->getChange();
        content_.erase(content_.length() - lastChange.length());
        changes_.pop_back();
    }
};

2. 多状态备忘录

复制代码
class FullStateMemento {
    std::string content_;
    int cursorPosition_;
    std::vector<std::string> openFiles_;
    // 可以保存更多状态...
    
    friend class IDE;
    FullStateMemento(const std::string& content, int pos, const std::vector<std::string>& files)
        : content_(content), cursorPosition_(pos), openFiles_(files) {}
};

class IDE {
    // 各种状态...
public:
    std::unique_ptr<FullStateMemento> save() {
        return std::make_unique<FullStateMemento>(content_, cursorPos_, openFiles_);
    }
};

实际应用场景

  1. 文本编辑器:实现撤销/重做功能

  2. 游戏开发:保存游戏进度和存档

  3. 图形软件:绘图步骤的撤销

  4. 事务管理:操作回滚

  5. 配置管理:系统配置的保存和恢复

相关推荐
常某某的好奇心1 天前
备忘录模式(Memento Pattern)
备忘录模式
YoseZang5 天前
【设计模式】GoF设计模式之备忘录模式(Memento Pattern)
设计模式·备忘录模式
01空间5 天前
设计模式简述(十七)备忘录模式
设计模式·备忘录模式
碎梦归途11 天前
23种设计模式-行为型模式之备忘录模式(Java版本)
java·jvm·设计模式·软考·备忘录模式·软件设计师·行为型模式
hope_wisdom15 天前
实战设计模式之备忘录模式
设计模式·系统架构·软件工程·备忘录模式·架构设计
tuodianke22 天前
记录待办事项的便签软件有没有推荐的?
笔记·职场发展·软件需求·备忘录模式
搞不懂语言的程序员22 天前
备忘录模式深度解析与实战案例
数据库·python·备忘录模式
wenbin_java1 个月前
设计模式之备忘录模式:对象状态的可逆时光机
java·设计模式·备忘录模式
nlog3n1 个月前
Java备忘录模式详解
java·python·备忘录模式