1.意图
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样就可以将以后的对象状态恢复到先前保存的状态。
2.动机
有时有必要记录一个对象的内部状态。为了允许用户取消不确定的操作或从错误中恢复过来,需要实现检查点和取消机制,你必须事先将状态信息保存在某处,这样才能将对象恢复到它们先前的状态。但是对象通常封装了其不封或所有的状态信息,使得其状态不能被其他对象访问,也就不可能在该对象之外保存其状态。而暴露其内部状态又将违反封装的原则,可能有损应用的可靠性和可扩展性。
3.结构与参与者
4.效果
1)保持封装边界
使用备忘录就是为了封装原发其的信息,这样既可返回原来的状态,也使得信息不暴露。面向接口编程。
2)它简化了原发器
在其他的保持封装性的设计中,Originator负责存储客户请求存储的原始状态。现在由Memento类进行存储。
3)使用备忘录可能代价很高(缺)
如果存储的信息过大,或者操作过于频繁,那么开销会很大,此时备忘录模式就不太合适了。
4)定义窄接口和宽接口
在一些语言中可能难以保证只有原发器可访问备忘录的状态。
5)维护备忘录的潜在代价(缺)
管理器负责删除它所能维护的备忘录。然而管理器不知道备忘录中有多少个状态。因此当存储备忘录时,一个本来很小的管理器,可能会产生大量的存储开销。
5.实现
1)语言支持
备忘录有两个接口:一个为原发其所使用的宽接口,一个为其他对象所使用的窄接口。理想的实现语言应可支持两级的静态保护。在C++中,可将Originator作为Memento的一个友元,并使Memento宽接口为私有,只有窄接口应该被声明为公共的。
2)存储增量式改变
如果备忘录的创建及其返回(给它们的原发器)的顺序是可预测的,备忘录可以仅存储原发起内部状态的增量改变。
6.代码示例
#include <iostream>
#include <string>
using namespace std;
class Memo;
//封装的数据
class State
{
public:
State(int health,int attack,int defense):m_health(health),m_attack(attack),m_defense(defense){}
int GetHealth(){return m_health;}
int GetAttack(){return m_attack;}
int GetDefense(){return m_defense;}
void SetHealth(int health){m_health=health;}
void SetAttack(int attack){m_attack=attack;}
void SetDefense(int defense){m_defense=defense;}
private:
int m_health;
int m_attack;
int m_defense;
};
//发起人类
class Originator
{
public:
Originator(State* state):_state(state){}
Memo* CreateMemo();
State* GetState()
{
return _state;
}
void SetMemo(Memo* memo);
void Show()
{
cout<<"生命值:"<<_state->GetHealth()<<endl;
cout<<"攻击力:"<<_state->GetAttack()<<endl;
cout<<"防御力:"<<_state->GetDefense()<<endl;
}
private:
State* _state;
};
//备忘录类
class Memo
{
public:
Memo(State* state)
{
_state=new State(state->GetHealth(),state->GetAttack(),state->GetDefense());
}
private:
friend class Originator;
State* GetState()
{
return _state;
}
State* _state;
};
Memo* Originator::CreateMemo()
{
return new Memo(_state);
}
void Originator::SetMemo(Memo* memo)
{
_state = memo->GetState();
}
//管理者类
class Caretaker
{
public:
Memo* memo;
};
//客户端:
int main()
{
void FightBoss(Originator* on);
State* pState=new State(1000,200,100);
Originator* on=new Originator(pState);
Caretaker* ct=new Caretaker();
cout << "人物初始化完成"<<endl;
on->Show();
ct->memo = on->CreateMemo();
cout << "存档完成"<<endl;
FightBoss(on);
on->Show();
cout << "加载存档"<<endl;
on->SetMemo(ct->memo);
on->Show();
return 0;
}
void FightBoss(Originator* on)
{
on->GetState()->SetHealth(0);
on->GetState()->SetAttack(0);
on->GetState()->SetDefense(0);
cout << "对抗BOSS"<<endl;
}
![](https://img-my.csdn.net/uploads/201303/09/1362791238_6354.jpg)