1、备忘录模式(Memento),Memento模式,没有人想犯错误,但是没有人能够不犯错误。犯了错误一般只能改过,却很难改正(恢复)。 世界上没有后悔药,但是我们在进行软件系统的设计时候是要给用户后悔的权利(实际上可能也是用户要求的权利),我们对一些关键性的操作肯定需要提供诸如撤销(Undo)的操作。那这个后悔药就是Memento模式提供的。,Memento模式的关键就是要在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以利用该保存的状态实施恢复操作。 Memento模式的典型结构图为:,Memento模式基本代码,class Originator pri
2、vate string state;public string Stateget return state; set state = value; public Memento CreateMemento()return (new Memento(state);public void SetMemento(Memento memento)state = memento.State;public void Show()Console.WriteLine(“State=“ + state);,备忘录类,class Mementoprivate string state;public Memento
3、(string state)this.state = state;public string Stateget return state; ,管理者类,class Caretakerprivate Memento memento;public Memento Mementoget return memento; set memento = value; ,客户端,class Programstatic void Main(string args)Originator o = new Originator();o.State = “On“;o.Show();Caretaker c = new C
4、aretaker();c.Memento = o.CreateMemento();o.State = “Off“;o.Show();o.SetMemento(c.Memento);o.Show();Console.Read();,优点:,有时一些发起人对象的内部信息必须保存在发起人对象以外的地方,但是必须要由发起人对象自己读取,这时,使用备忘录模式可以把复杂的发起人内部信息对其他的对象屏蔽起来,从而可以恰当地保持封装的边界。 本模式简化了发起人类。发起人不再需要管理和保存其内部状态的一个个版本,客户端可以自行管理他们所需要的这些状态的版本。 当发起人角色的状态改变的时候,有可能这个状态无效,这
5、时候就可以使用暂时存储起来的备忘录将状态复原。,缺点: 如果发起人角色的状态需要完整地存储到备忘录对象中,那么在资源消耗上面备忘录对象会很大。 当负责人角色将一个备忘录 存储起来的时候,负责人可能并不知道这个状态会占用多大的存储空间,从而无法提醒用户一个操作是否很大。,适用场合: 如果必须保存一个对象在某一个时刻的全部或者部分状态,方便在以后需要的时侯,可以把该对象恢复到先前的状态,可以使用备忘录模式,本质,保存和恢复内部状态,备忘录模式和原型模式,这两个模式可以组合使用 在原发器对象(发起人对象)创建备忘录对象的时候,如果原发器对象中全部或者大部分的状态都需要保存,一个简洁的方式就是直接克隆
6、一个原发器对象。也就是说,这个时候备忘录对象里面存放的是一个原发器对象的实例。,游戏进度备忘,游戏角色,class GameRoleprivate int vit; /生命力public int Vitalityget return vit; set vit = value; private int atk; /攻击力public int Attackget return atk; set atk = value; private int def; /防御力public int Defenseget return def; set def = value; ,public void State
7、Display()Console.WriteLine(“角色当前状态:“);Console.WriteLine(“体力:0“, this.vit);Console.WriteLine(“攻击力:0“, this.atk);Console.WriteLine(“防御力:0“, this.def);Console.WriteLine(“);/保存角色状态public RoleStateMemento SaveState()return (new RoleStateMemento(vit, atk, def);/恢复角色状态public void RecoveryState(RoleStateMem
8、ento memento)this.vit = memento.Vitality;this.atk = memento.Attack;this.def = memento.Defense;,/获得初始状态public void GetInitState()this.vit = 100;this.atk = 100;this.def = 100;/战斗public void Fight()this.vit = 0;this.atk = 0;this.def = 0;,角色状态存储箱,class RoleStateMementoprivate int vit;private int atk;pri
9、vate int def;public RoleStateMemento(int vit, int atk, int def)this.vit = vit;this.atk = atk;this.def = def;/生命力public int Vitalityget return vit; set vit = value; ,/攻击力public int Attackget return atk; set atk = value; /防御力public int Defenseget return def; set def = value; ,角色状态管理者,class RoleStateCa
10、retakerprivate RoleStateMemento memento;public RoleStateMemento Mementoget return memento; set memento = value; ,static void Main(string args)/大战Boss前GameRole lixiaoyao = new GameRole();lixiaoyao.GetInitState();lixiaoyao.StateDisplay();/保存进度RoleStateCaretaker stateAdmin = new RoleStateCaretaker();stateAdmin.Memento = lixiaoyao.SaveState();/大战Boss时,损耗严重lixiaoyao.Fight();lixiaoyao.StateDisplay();/恢复之前状态lixiaoyao.RecoveryState(stateAdmin.Memento);lixiaoyao.StateDisplay();Console.Read();,