一、引言
备忘录模式(Memento Pattern)是一种行为型设计模式,它允许在不暴露对象内部状态的情况下保存和恢复对象的状态。这种模式通过备忘录对象来保存对象的内部状态,实现了对象状态的快照功能,常用于实现撤销操作。
二、使用场景
-
实现撤销/重做功能:在需要提供撤销和重做功能的应用程序中,如文本编辑器、绘图程序等,备忘录模式能够轻松实现这一需求。
-
状态记录与恢复:对于需要监控状态变化并能够恢复到先前状态的场景设计,备忘录模式提供了一种简便的方案。
-
数据较大时的快照:对于状态较多或复杂的对象,可以通过备忘录模式利用其快照功能方便地保存之前状态,方便后期检索和恢复。
-
构建时间和空间复杂度要求高的场景:可以通过备忘录进行内存优化,避免不必要的重复创建,同时合理保留对象的内部状态。
三、模式分类
- 单备忘录:一个状态对应一个备忘录,备忘录存储的通常是某个对象的当前状态。
- 多备忘录:为不同的状态创建多个备忘录,例如维护多个历史版本的快照。
四、优缺点
优点
- 封装性:对象的内部状态被封装到备忘录中,调用者无法直接访问对象的内部数据。
- 提醒撤销时巨大的灵活性:用户可以轻松撤销到任意先前状态,而不需要将状态保留在对象自身。
- 简化原始对象:使得原始对象无需为实现撤销的操作而承担多余的复杂性。
缺点
- 内存消耗:创建备忘录可能会消耗很多内存,特别是对于状态频繁变化的对象来说,一旦创建大量的备忘录会占用过多资源。
- 实现复杂性:管理备忘录的生命周期可能使得代码复杂,尤其是在涉及多个对象及备忘录时,可能需要额外的管理逻辑。
- 不支持时特复杂状态:如果需要深度对备忘录模式的支持,可能会需要借助额外的机制进行状态的监控和更改。
五、代码示例
以下是使用备忘录模式的C++实现示例。
#include <iostream>
#include <string>
#include <vector>
#include <memory>
// 备忘录类
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; // 获取当前状态
}
// 创建备忘录
std::shared_ptr<Memento> saveToMemento() {
return std::make_shared<Memento>(this->state); // 保存当前状态
}
// 从备忘录恢复状态
void restoreFromMemento(std::shared_ptr<Memento> memento) {
state = memento->getState(); // 复原状态
}
};
// 管理员类
class Caretaker {
private:
std::vector<std::shared_ptr<Memento>> mementoList; // 备忘录容器
public:
void addMemento(std::shared_ptr<Memento> memento) {
mementoList.push_back(memento);
}
std::shared_ptr<Memento> getMemento(int index) const {
if (index < 0 || index >= static_cast<int>(mementoList.size())) {
throw std::out_of_range("Index out of range"); // 检查索引范围
}
return mementoList.at(index); // 获取指定备忘录
}
};
int main() {
Originator originator; // 创建原发器
Caretaker caretaker; // 创建管理员
// 设置状态并保存备忘录
originator.setState("State 1");
caretaker.addMemento(originator.saveToMemento());
originator.setState("State 2");
caretaker.addMemento(originator.saveToMemento());
originator.setState("State 3");
caretaker.addMemento(originator.saveToMemento());
// 还原状态
originator.restoreFromMemento(caretaker.getMemento(1)); // 还原为 State 2
std::cout << "Restored to: " << originator.getState() << std::endl; // 输出当前状态
return 0;
}
代码解析
-
Memento:备忘录类,包含记录状态的属性和获取状态的方法。
-
Originator:原发器类,负责设置和获取当前状态,支持保存状态到备忘录和从备忘录恢复状态。
-
Caretaker:管理类,用于持有备忘录列表并负责保存和恢复备忘录。
-
main():在主函数中,首先创建原发器和管理员对象,设置状态并生成备忘录,然后在需要时通过管理员获取备忘录,并使用原发器进行恢复。控制台输出恢复的状态。
六、模式总结
备忘录模式是管理对象状态的一种优雅方式,使得对象能够在不突破封装性的情况下进行状态恢复以及记录,常用于实现日志和撤销功能。尽管它有较高的内存消耗与管理复杂性等问题,但在合适的情况下,备忘录模式能够显著提高系统的灵活性、减少耦合,提供便捷的状态管理。理解和合理运用备忘录模式是软件设计中的一项重要技能,这有助于构建可维护和可扩展的应用系统。
没有回复内容