备忘录模式适用于实现c++++程序中对象状态的保存与恢复,且不破坏封装性。其主要包括三个角色:发起人(originator)负责创建和恢复备忘录;备忘录(memento)存储状态并仅允许发起人访问;管理者(caretaker)保存但不操作备忘录内容。设计时应定义清晰的备忘录类,通常为私有或嵌套于发起人类中,并根据需要扩展字段或优化内存使用。发起人类需提供生成和恢复备忘录的方法,复杂状态下应做深拷贝。管理者常使用栈或列表保存历史记录,支持撤销、重做功能,并可通过限制保存数量控制内存消耗。其他实现建议包括封装控制、性能优化、线程安全及序列化支持。

在设计C++程序时,如果你需要实现对象状态的保存与恢复(比如实现“撤销”功能),备忘录模式是一个非常合适的解决方案。它能帮助你在不破坏对象封装性的前提下,捕获并外部化对象的内部状态。

备忘录模式的基本结构
备忘录模式通常包括三个角色:

- 发起人(Originator):负责创建一个备忘录来存储它的内部状态,并可以使用备忘录恢复状态。
- 备忘录(Memento):用于存储发起人的状态,通常只允许发起人访问其内容。
- 管理者(Caretaker):负责保存备忘录对象,但不能检查或操作其内容。
关键点在于保持封装性的同时,把状态存储和恢复逻辑分离出来。
立即学习“C++免费学习笔记(深入)”;
定义清晰的备忘录类
备忘录类(Memento)是整个模式的核心,它应该包含足够的信息来还原发起人对象的状态。

class Memento {
private:
std::string state;
public:
explicit Memento(const std::string& state) : state(state) {}
std::string getState() const { return state; }
};这个类一般会设置为私有或嵌套在发起人类中,以防止其他类直接访问其状态。
- 可以根据实际需求扩展成更复杂的结构,比如保存多个字段、时间戳等。
- 如果状态数据较大,可以考虑使用智能指针或共享资源管理方式来优化内存使用。
发起人类的设计要点
发起人类需要能够生成备忘录,并从备忘录中恢复状态。
class Originator {
private:
std::string state;
public:
void setState(const std::string& state) { this->state = state; }
std::string getState() const { return state; }
Memento saveToMemento() const {
return Memento(state);
}
void restoreFromMemento(const Memento& memento) {
state = memento.getState();
}
};- 注意
saveToMemento()和restoreFromMemento()的设计要简单明了。 - 如果状态复杂,可以在恢复时做深拷贝,避免引用问题。
管理者如何安全地保存历史记录
管理者的作用是保存一系列备忘录对象,以便后续恢复。
class Caretaker {
private:
std::vector history;
public:
void addMemento(const Memento& memento) {
history.push_back(memento);
}
Memento getMemento(int index) const {
return history[index];
}
}; - 常见用法是配合栈或列表结构来支持“撤销”、“重做”等功能。
- 为了节省内存,可以限制最大保存数量,或者定期清理旧状态。
例如:
- 撤销最近一次操作:取出最后一个备忘录进行恢复
- 支持多级撤销:维护一个索引指向当前状态位置
- 自动保存快照:每隔一定操作次数保存一次状态
实现细节上的几点建议
- 封装控制:可以把 Memento 类设为 Originator 的私有嵌套类,这样外部无法直接构造或修改它。
- 性能优化:如果对象状态很大,不要每次都完整保存,可以采用差异保存或压缩机制。
- 线程安全:在并发环境中使用时,注意对 Caretaker 的访问加锁保护。
- 序列化支持:如果你想持久化保存状态,可以让 Memento 支持序列化/反序列化接口。
基本上就这些。只要结构清晰,实现起来并不复杂,但在大型项目中容易被忽略的是状态一致性管理和内存开销控制。










