C++备忘录模式:优雅实现对象状态保存与恢复
在开发中,我们常会遇到需要撤销操作、历史记录或状态回滚的场景。备忘录模式(Memento Pattern)正是为此而生。它允许在不破坏封装性的前提下捕获对象的内部状态,以便后续恢复。今天我们就来聊聊如何在 C++ 中落地这一模式,顺便避避坑。
核心角色解析
理解备忘录模式,关键看三个角色怎么配合:
1. Originator(发起人)
这是需要保存状态的对象。它负责创建备忘录并记录当前状态,也能利用备忘录恢复之前的状态。简单来说,它是状态的拥有者。
2. Memento(备忘录)
这是存储 Originator 状态的对象。它有两个接口:宽接口供 Originator 使用以存取数据,窄接口供其他对象使用仅用于保存。这样既保证了数据能存下来,又防止了外部随意修改内部细节。
3. Caretaker(管理者)
它只负责管理备忘录对象,比如存一堆快照。CareTaker 不操作备忘录内容,只能通过窄接口交互。职责单一,耦合度低。
设计原则体现
这个模式其实暗合了不少设计原则:
- 单一职责:把状态保存从业务逻辑里剥离出来,Originator 专心干活。
- 开闭原则:想扩展保存功能?加个新备忘录类就行,不用改 Originator。
- 迪米特法则:Caretaker 不懂 Memento 内部细节,系统更松耦合。
C++ 实战代码
下面是一个完整的示例。注意,这里我用了智能指针来管理内存,避免手动 delete 带来的泄漏风险,这在 C++ 里是必须的。
#include <iostream>
#include <string>
#include <vector>
#include <memory>
// 备忘录类:存储状态
// 只有 Originator 可以通过友元访问私有成员
class Memento {
private:
std::string state;
friend class Originator;
Memento(const std::string& s) : state(s) {}
public:
// 窄接口:获取状态(通常由 Originator 调用)
std::string GetState() const { state; }
};
{
:
std::string state;
:
{
std::cout << << s << std::endl;
state = s;
}
{
std::<Memento>(state);
}
{
state = m->();
std::cout << << state << std::endl;
}
};
{
:
std::vector<std::unique_ptr<Memento>> mementos;
Originator* originator;
:
(Originator* orig) : (orig) {}
{
mementos.(originator->());
}
{
(mementos.()) ;
m = mementos.();
originator->(m.());
mementos.();
}
};
{
Originator originator;
;
originator.();
caretaker.();
originator.();
caretaker.();
originator.();
caretaker.();
caretaker.();
;
}


