声明:本博文篇幅短,适合review。
一、概念
在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
二、模式结构图
class Memento {
private:
string mState;
public:
Memento()
{
mState = "";
}
Memento(string state){
this->mState = state;
}
string getState() {
return mState;
}
};
class Originator {
private :
string mState;
public:
Originator()
{
mState = "";
}
string getState() {
return mState;
}
void setState(string state) {
this->mState = state;
}
Memento createMemento(){
return Memento(this->mState);
}
void restoreMemento(Memento memento){
this->setState(memento.getState());
}
};
class Caretaker {
private :
Memento memento;
public :
Memento getMemento(){
return memento;
}
void setMemento(Memento memento){
this->memento = memento;
}
};
void main()
{
Originator originator;
originator.setState("State 1");
cout<<"Init State:"<<originator.getState()<<endl;
Caretaker caretaker;
caretaker.setMemento(originator.createMemento());
originator.setState("State 2");
cout<<"Changed State:"<<originator.getState()<<endl;
originator.restoreMemento(caretaker.getMemento());
cout<<"Restore State:"<<originator.getState()<<endl;
}
三、例子
class Save
{
private:
int mHealthy;
int mAttack;
public:
Save(int healthy, int attack):
mHealthy(healthy),mAttack(attack) {}
int getHealthy(){
return mHealthy;
}
int getAttack(){
return mAttack;
}
};
class GameRole
{
private:
int mHealthy;
int mAttack;
public:
GameRole(): mHealthy(100),mAttack(80) {}
Save createSave()
{
return Save(mHealthy, mAttack);
}
void loadSave(Save save)
{
mHealthy = save.getHealthy();
mAttack = save.getAttack();
}
void show() {
cout<<"Healthy : "<< mHealthy<<", Attack : "<< mAttack<<endl;
}
void fight() {
mHealthy -= 10;
mAttack -= 10;
}
};
class SaveManager
{
public:
void saveOne(Save save) {
mVec.push_back(save);
}
Save loadOne(int index) {
return mVec[index];
}
private:
vector<Save> mVec;
};
void main()
{
SaveManager sm;
GameRole role;
role.show(); //初始值
sm.saveOne(role.createSave()); //保存状态
role.fight();
role.show(); //进攻后
role.loadSave(sm.loadOne(0)); //载入状态
role.show(); //恢复到初始值
}
四、优缺点
1、优点
a、当发起人角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。
b、简化了发起人类,发起人不再需要管理和保存其内部状态的一个个版本。
c、把复杂的发起人内部信息对其他的对象屏蔽起来,从而可以恰当地保持封装的边界。
2、缺点
a、如果备份的对象存在大量的信息或者创建、恢复操作非常频繁,则可能造成很大的性能开销。