说是客户端瘦身,其实备忘录模式的本质让调用客户端职责减轻,将客户端的对于实现比如数据恢复之类细节的内容封装在操作类之中。其实面向对象的一重要方面就是划分清楚职责,这样可以减少改到造成的影响,便于扩展。
Originator的职责是负责备忘录数据对象的生产以及回复,并保存当前版本数据对象,Originator本身是“宽接口”,可以对备忘数据进行修改和读取;
CareTaker则是负责备忘数据的存储,具有“窄接口”,可以只提供对备忘数据的读取功能。
Memento数据实体,Memento对象可以是结构,也可以实现IClone接口以实现原型模式,因为Originator在保存备忘的时候是希望能够返回一个全新的对象,而不是被关联的对象。
示例:
实现类
public class Originator { public Memento myMemento = null; public Memento SaveMemento() { return myMemento.Clone() as Memento; } public void SetMemento(Memento pMemento) { this.myMemento = pMemento; } } public class Memento : ICloneable { public string Name; public string Address; public int Age; public object Clone() { return this.MemberwiseClone(); } } public class CareTaker { private Memento myMemento = null; public Memento MyMemento { get { return myMemento; } set { myMemento = value; } } }
调用客户端
class Program { static void Main(string[] args) { Memento m = new Memento(); m.Address = "Beijing"; m.Age = 23; m.Name = "Lorry"; Originator org = new Originator(); org.SetMemento(m); Console.WriteLine("Address:{0}; Age:{1}", org.myMemento.Address, org.myMemento.Age); CareTaker taker = new CareTaker(); taker.MyMemento = org.SaveMemento(); org.myMemento.Address = "Dalian"; org.myMemento.Age = 34; Console.WriteLine("Address:{0}; Age:{1}", org.myMemento.Address, org.myMemento.Age); org.SetMemento(taker.MyMemento); Console.WriteLine("Address:{0}; Age:{1}", org.myMemento.Address, org.myMemento.Age); Console.Read(); } }