介紹
在不破壞一個對象封裝性的情況下,捕獲對象內(nèi)部的狀態(tài),并在這個對象之外保存內(nèi)部狀態(tài),以便可以恢復(fù)相關(guān)狀態(tài)
參與者
- Memnto//備忘錄
- Originator//原發(fā)器
- CareTaker //負責(zé)人 只能存儲,加載Memntor不能訪問數(shù)據(jù)
代碼實現(xiàn)
struct PlayData{
int kill_num;
int dead_num;
int assistant_num;
};
class Game;
class Memento {
public:
Memento *loadFromDisk()
{
std::cout<<"正在從數(shù)據(jù)庫中讀取....."<<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<<"正在存入數(shù)據(jù)庫中....."<<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;
//假設(shè)已經(jīng)保存了
auto mem = careTaker.getMemFromDB();
g.setMemnto(mem);
g.printState();
std::cout<<"繼續(xù)上局游戲后:"<<std::endl;
g.kill();g.kill();g.kill();
g.dead();
g.assistant();
auto tosave = g.createMem();
g.printState();
careTaker.saveMemnto(tosave);
return 0;
}
輸出結(jié)果
正在從數(shù)據(jù)庫中讀取.....
K:10 D:3 A:22
繼續(xù)上局游戲后:
K:13 D:4 A:23
正在存入數(shù)據(jù)庫中.....
特點
- 保持封裝邊界
- 簡化了原發(fā)器
- 使用備忘錄的代價可能很高
- 定義寬接口和窄接口
參考
- 《設(shè)計模式:可復(fù)用面向?qū)ο筌浖_發(fā)的基礎(chǔ)》
- https://www.cnblogs.com/zyrblog/p/9249660.html