介绍
在不破坏一个对象封装性的情况下,捕获对象内部的状态,并在这个对象之外保存内部状态,以便可以恢复相关状态
参与者
- Memnto//备忘录
- Originator//原发器
- CareTaker //负责人 只能存储,加载Memntor不能访问数据
代码实现
struct PlayData{
int kill_num;
int dead_num;
int assistant_num;
};
class Game;
class Memento {
public:
Memento *loadFromDisk()
{
std::cout<<"正在从数据库中读取....."<<std::endl;
auto *memento = new Memento();
memento->data.kill_num = 10;
memento->data.dead_num = 3;
memento->data.assistant_num = 22;
return memento;
}
void saveMemnto()
{
std::cout<<"正在存入数据库中....."<<std::endl;
}
private:
friend class Game;
PlayData data;
};
class Game{
public:
Game()
{
data.assistant_num = 0;
data.kill_num = 0;
data.dead_num = 0;
}
void kill()
{
++data.kill_num;
}
void dead()
{
++data.dead_num;
}
void assistant()
{
++data.assistant_num;
}
Memento *createMem()
{
auto *memento = new Memento();
memento->data = data;
return memento;
}
void setMemnto(Memento *memento)
{
data = memento->data;
}
void printState()
{
std::cout<<"K:"<<data.kill_num<<" D:"<<data.dead_num<<" A:"<<data.assistant_num<<std::endl;
}
private:
PlayData data;
};
class CareTaker {
public:
Memento *getMemFromDB()
{
auto *memento = new Memento();
return memento->loadFromDisk();
}
void saveMemnto(Memento *mem)
{
mem->saveMemnto();
}
};
int main()
{
Game g;
CareTaker careTaker;
//假设已经保存了
auto mem = careTaker.getMemFromDB();
g.setMemnto(mem);
g.printState();
std::cout<<"继续上局游戏后:"<<std::endl;
g.kill();g.kill();g.kill();
g.dead();
g.assistant();
auto tosave = g.createMem();
g.printState();
careTaker.saveMemnto(tosave);
return 0;
}
输出结果
正在从数据库中读取.....
K:10 D:3 A:22
继续上局游戏后:
K:13 D:4 A:23
正在存入数据库中.....
特点
- 保持封装边界
- 简化了原发器
- 使用备忘录的代价可能很高
- 定义宽接口和窄接口
参考
- 《设计模式:可复用面向对象软件开发的基础》
- https://www.cnblogs.com/zyrblog/p/9249660.html