首页 短视频

C++ 设计模式实战:深入剖析备忘录模式的原理与应用(附代码示例)

分类:短视频
字数: (5337)
阅读: (0746)
内容摘要:C++ 设计模式实战:深入剖析备忘录模式的原理与应用(附代码示例),

在软件开发过程中,经常会遇到需要保存对象状态并在后续某个时刻恢复的需求。例如,文本编辑器的撤销/重做功能,游戏中的存档/读档功能,数据库事务的回滚操作等等。备忘录模式 正是为了解决这类问题而生的。它提供了一种在不破坏封装性的前提下,捕获并外部化对象内部状态的方法,从而可以在稍后将对象恢复到先前的状态。

问题场景重现:文本编辑器的撤销功能

假设我们正在开发一个简单的文本编辑器。用户可以在编辑器中输入文本,并可以进行撤销操作。每次撤销操作都需要将编辑器恢复到之前的状态。如果不使用备忘录模式,我们可以直接保存编辑器的文本内容,但这会导致代码的紧耦合,且不符合面向对象的设计原则。

C++ 设计模式实战:深入剖析备忘录模式的原理与应用(附代码示例)

底层原理深度剖析:备忘录模式的组成

备忘录模式主要包含以下几个角色:

C++ 设计模式实战:深入剖析备忘录模式的原理与应用(附代码示例)
  • Originator (发起人): 负责创建备忘录,并在需要时从备忘录中恢复自身状态。它知道如何将自身状态保存到备忘录中,以及如何从备忘录中恢复状态。
  • Memento (备忘录): 用于存储Originator的内部状态。备忘录应该对Originator以外的对象隐藏其内部状态,以保证封装性。
  • Caretaker (管理者): 负责保存备忘录,但不检查备忘录的内容。它可以存储多个备忘录,以便实现多次撤销/重做功能。

C++ 代码实现:简单的文本编辑器备忘录

#include <iostream>
#include <string>
#include <vector>

// 备忘录类
class EditorMemento {
public:
    EditorMemento(const std::string& text) : text_(text) {}
    std::string getText() const { return text_; }
private:
    std::string text_;
};

// 发起人类
class TextEditor {
public:
    void setText(const std::string& text) { text_ = text; }
    std::string getText() const { return text_; }
    EditorMemento save() {
        return EditorMemento(text_); // 创建备忘录
    }
    void restore(const EditorMemento& memento) {
        text_ = memento.getText(); // 从备忘录恢复状态
    }
private:
    std::string text_;
};

// 管理者类
class History {
public:
    void push(const EditorMemento& memento) { history_.push_back(memento); }
    EditorMemento pop() {
        EditorMemento memento = history_.back();
        history_.pop_back();
        return memento;
    }
private:
    std::vector<EditorMemento> history_;
};

int main() {
    TextEditor editor;
    History history;

    editor.setText("Hello");
    history.push(editor.save()); // 保存状态

    editor.setText("Hello World");
    history.push(editor.save()); // 保存状态

    std::cout << "Current Text: " << editor.getText() << std::endl; // 输出:Hello World

    editor.restore(history.pop()); // 撤销
    std::cout << "Text after undo: " << editor.getText() << std::endl; // 输出:Hello

    editor.restore(history.pop()); // 撤销
    std::cout << "Text after undo: " << editor.getText() << std::endl; // 输出:Hello

    return 0;
}

实战避坑经验总结:备忘录模式的注意事项

  1. 内存管理: 备忘录模式可能会导致大量的内存占用,特别是当保存的状态信息非常复杂时。需要考虑如何有效地管理备忘录的生命周期,例如使用智能指针或定期清理不必要的备忘录。
  2. 序列化: 如果需要将备忘录持久化到磁盘或者通过网络传输,需要考虑如何序列化备忘录中的数据。C++ 中常用的序列化方法包括 Boost.Serialization 和 Google Protocol Buffers。
  3. 深拷贝 vs. 浅拷贝: 在创建备忘录时,需要注意深拷贝和浅拷贝的区别。如果对象包含指针成员,需要进行深拷贝,以避免多个备忘录指向同一块内存区域。
  4. 状态复杂度: 对于大型对象,全部状态的拷贝代价可能很高。可以考虑只保存需要撤销/重做的关键状态,或者使用增量备份的方式,只保存状态的变更部分。
  5. 多线程安全: 在多线程环境下使用备忘录模式时,需要注意线程安全问题。例如,多个线程可能同时访问同一个Originator,需要使用互斥锁或其他同步机制来保护Originator的状态。

在实际应用中,我们经常将备忘录模式与命令模式结合使用,实现更复杂的撤销/重做功能。 例如,在 Nginx 配置管理工具中,可以使用备忘录模式来保存 Nginx 配置文件的修改历史,并在出现错误时回滚到之前的配置。 这类似于宝塔面板中的备份回滚功能, 保证服务器稳定。

C++ 设计模式实战:深入剖析备忘录模式的原理与应用(附代码示例)

总结

备忘录模式是一种非常有用的设计模式,它可以帮助我们实现状态的保存和恢复,从而提高应用程序的健壮性和灵活性。掌握备忘录模式的原理和应用,对于构建高质量的 C++ 应用程序至关重要。

C++ 设计模式实战:深入剖析备忘录模式的原理与应用(附代码示例)

C++ 设计模式实战:深入剖析备忘录模式的原理与应用(附代码示例)

转载请注明出处: DevOps小王子

本文的链接地址: http://m.acea1.store/article/89372.html

本文最后 发布于2026-04-07 16:44:36,已经过了20天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 臭豆腐爱好者 4 天前
    大佬讲的很透彻,关于深拷贝和浅拷贝的坑,之前踩过,深有体会!