M:在不破坏封装性的前提下,捕获一个对象(备忘录)的内部状态,并在该对象之外保存(管理备忘录)这个状态。这样以后就可将该对象恢复到原先保存的状态。
保存的细节给封装在了Memento中了,哪一天要更改保存的细节也不用影响客户端。
When use?
适用于功能比较复杂,但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分时,可以根据保存的Memento信息还原到前一状态。
如果在某个系统中使用命令模式时,需要实现命令的撤消功能,那么命令模式可以使用备忘录模式存储可撤销操作的状态。使用备忘录可以把复杂的对象内部信息对其他的对象屏蔽起来。
当角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。
游戏角色
class GameRole
{
private int vitality = 100;
private int attack = 100;
private int defense = 100;
//获取备忘录状态
public RoleMemento GetState()
{
return new RoleMemento(vitality, attack, defense);
}
//保存备忘录状态
public RoleMemento SaveState()
{
return new RoleMemento(vitality, attack, defense);
}
//恢复备忘录
public void RecoverState(RoleMemento roleMemento)
{
this.vitality = roleMemento.Vitality;
this.attack = roleMemento.Attack;
this.defense = roleMemento.Defense;
}
public void DisplayState()
{
Console.WriteLine(string.Format("生命力是{0}", vitality));
Console.WriteLine(string.Format("攻击力是{0}", attack));
Console.WriteLine(string.Format("防御力是{0}", defense));
}
public void Fight()
{
this.vitality = 0;
this.attack = 0;
this.defense = 0;
}
}
角色备忘录
class RoleMemento
{
private int vitality;
private int attack;
private int defense;
public RoleMemento(int vitality, int attack, int defense)
{
this.vitality = vitality;
this.attack = attack;
this.defense = defense;
}
public int Vitality
{
get { return vitality; }
set { vitality = value; }
}
public int Attack
{
get { return attack; }
set { attack = value; }
}
public int Defense
{
get { return defense; }
set { defense = value; }
}
}
保存备忘录
class RoleStateCaretaker
{
private RoleMemento roleMemento;
public RoleMemento RoleMemento
{
get { return roleMemento; }
set { roleMemento = value; }
}
}
客户端调用
GameRole gr = new GameRole();
gr.GetState();
gr.DisplayState();
RoleStateCaretaker rsc = new RoleStateCaretaker();
rsc.RoleMemento = gr.SaveState();
gr.Fight();
gr.SaveState();
gr.DisplayState();
gr.RecoverState(rsc.RoleMemento);
gr.DisplayState();