引言
做开发时,我们常遇到需要撤销操作、历史记录或状态回滚的场景。备忘录模式(Memento Pattern)正是为了解决这类问题而生的设计工具。它允许在不破坏封装性的前提下,捕获并外部化一个对象的内部状态,以便后续恢复到原先保存的状态。
备忘录模式概述
这是一种行为设计模式,特别适合需要实现撤销功能、快照记录的场景。核心在于将状态保存的职责从业务逻辑中剥离,让对象本身专注于核心功能。
核心角色解析
发起人 (Originator)
这是需要保存状态的对象。它负责创建备忘录来记录当前状态,也能利用备忘录恢复之前的状态。关键在于它知道如何正确保存和恢复自身数据。
备忘录 (Memento)
作为状态的容器,它存储 Originator 的内部信息。为了维护封装性,它通常提供两个接口:宽接口供 Originator 使用以存取状态,窄接口供其他对象使用仅用于传递引用。
管理者 (Caretaker)
负责管理备忘录的集合。它的职责是保存备忘录对象,但绝不操作备忘录的内容,只能通过窄接口与备忘录交互,从而确保状态细节不被意外修改。
设计原则体现
备忘录模式体现了几个关键的面向对象原则:
- 单一职责:将状态保存从 Originator 分离,使其专注业务逻辑。
- 开闭原则:无需修改 Originator 即可扩展保存功能,通过新增备忘录类实现。
- 迪米特法则:Caretaker 不直接操作 Memento 内部细节,降低系统耦合度。
C++ 实现示例
下面是一个完整的 C++ 实现。注意这里使用了 friend 关键字来平衡封装性与访问权限,同时用智能指针或手动管理内存时需格外小心。
#include <iostream>
#include <string>
#include <vector>
// 备忘录类
class Memento {
private:
std::string state;
// 只有 Originator 可以访问私有成员
friend class Originator;
Memento(const std::string& s) : state(s) {}
public:
std::string GetState() const {
return state;
}
};
// 发起人类
class {
:
std::string state;
:
{
std::cout << << s << std::endl;
state = s;
}
{
(state);
}
{
state = m->();
std::cout << << state << std::endl;
}
};
{
:
std::vector<Memento*> mementos;
Originator* originator;
:
(Originator* orig) : (orig) {}
~() {
( m : mementos) m;
}
{
mementos.(originator->());
}
{
(mementos.()) ;
Memento* m = mementos.();
originator->(m);
mementos.();
m;
}
};
{
Originator originator;
;
originator.();
caretaker.();
originator.();
caretaker.();
originator.();
caretaker.();
caretaker.();
;
}


