用以记录当前时刻自身的内部状态
原文:C#设计模式之二十二备忘录模式(Memento Pattern)【行为型】
一、引言
今天我们开始讲“行为型”设计模式的第十个模式,该模式是【备忘录模式】,英文名称是:Memento Pattern。按老端方,先从名称上来看看这个模式,小我私家的最初理解就是对某个东西的状态进行生存,等到需要恢复的时候,可以从备忘录中进行恢复。生活中这样的例子也能经常看到,如备份电话通讯录,备份操纵操纵系统,备份数据库等。如果我们想恢复东西的状态,那么我们可能首先想到的是把东西生存下来,但是这样会粉碎东西的封装性。因为东西有状态有操纵,如果我们为了生存东西而留着本来的东西,做一个深拷贝,那么其他东西也能通过这个东西的接口访谒这个东西状态,这并不是我们所但愿的。而我们需要它的职责只是生存和恢复东西状态,而不应在上面撑持对东西状态访谒的接口,这就孕育产生了Memento模式。
我们看上图,一个东西必定会有很多状态,这些状态必定会彼此改变而促进东西的成长,如果要想在某一时刻把当前东西答复到以前某一时刻的状态,这个情况用“备忘录模式”就能很好解决该问题。
二、备忘录模式的详细介绍
2.1、动机(Motivate)
在软件构建过程中,某些东西的状态在转换的过程中,可能由于某种需要,要求措施能够回溯到东西之前处于某个点时的状态。如果使用一些公有接口来让其他东西得到东西的状态,便会袒露东西的细节实现。
如何实现东西状态的良好生存与恢复,但同时又不会因此而粉碎东西自己的封装性?
2.2、意图(Intent)
在不粉碎封装性的前提下,捕获一个东西的内部状态,并在该东西之外生存这个状态(如果没有这个关键点,其实深拷贝就可以解决问题)。这样以后就可以将该东西恢复到原先生存的状态。 ——《设计模式》GoF
2.3、布局图(Structure)
2.4、模式的构成
可以看出,在备忘录模式的布局图有以下角色:
(1)、倡议人角色(Originator):记录当前时刻的内部状态,卖力创建和恢复备忘录数据。卖力创建一个备忘录Memento,用以记录当前时刻自身的内部状态,并可使用备忘录恢复内部状态。Originator【倡议人】可以按照需要决定Memento【备忘录】存储本身的哪些内部状态。
(2)、备忘录角色(Memento):卖力存储倡议人东西的内部状态,在进行恢复时供给给倡议人需要的状态,并可以防备Originator以外的其他东西访谒备忘录。备忘录有两个接口:Caretaker【打点角色】只能看到备忘录的窄接口,他只能将备忘录通报给其他东西。Originator【倡议人】却可看到备忘录的宽接口,允许它访谒返回到先前状态所需要的所有数据。
(3)、打点者角色(Caretaker):卖力生存备忘录东西。卖力备忘录Memento,不能对Memento的内容进行访谒或者操纵。
2.5、备忘录模式的代码实现
今天我们就用备份电话本的实例来说明备忘录模式的实现。实现代码如下:
1 namespace MementoPattern 2 { 3 // 联系人--需要备份的数据,是状态数据,没有操纵 4 public sealed class ContactPerson 5 { 6 //姓名 7 public string Name { get; set; } 8 9 //电话号码 10 public string MobileNumber { get; set; } 11 } 12 13 // 倡议人--相当于【倡议人角色】Originator 14 public sealed class MobileBackOriginator 15 { 16 // 倡议人需要生存的内部状态 17 private List<ContactPerson> _personList; 18 19 20 public List<ContactPerson> ContactPersonList 21 { 22 get 23 { 24 return this._personList; 25 } 26 27 set 28 { 29 this._personList = value; 30 } 31 } 32 //初始化需要备份的电话名单 33 public MobileBackOriginator(List<ContactPerson> personList) 34 { 35 if (personList != null) 36 { 37 this._personList = personList; 38 } 39 else 40 { 41 throw new ArgumentNullException("参数不能为空!"); 42 } 43 } 44 45 // 创建备忘录东西实例,将当期要生存的联系人列表生存到备忘录东西中 46 public ContactPersonMemento CreateMemento() 47 { 48 return new ContactPersonMemento(new List<ContactPerson>(this._personList)); 49 } 50 51 // 将备忘录中的数据备份还原到联系人列表中 52 public void RestoreMemento(ContactPersonMemento memento) 53 { 54 this.ContactPersonList = memento.ContactPersonListBack; 55 } 56 57 public void Show() 58 { 59 Console.WriteLine("联系人列表中共有{0}小我私家,他们是:", ContactPersonList.Count); 60 foreach (ContactPerson p in ContactPersonList) 61 { 62 Console.WriteLine("姓名: {0} 号码: {1}", p.Name, p.MobileNumber); 63 } 64 } 65 } 66 67 // 备忘录东西,用于生存状态数据,生存的是其时东西具体状态数据--相当于【备忘录角色】Memeto 68 public sealed class ContactPersonMemento 69 { 70 // 生存倡议人创建的电话名单数据,就是所谓的状态 71 public List<ContactPerson> ContactPersonListBack { get; private set; } 72 73 public ContactPersonMemento(List<ContactPerson> personList) 74 { 75 ContactPersonListBack = personList; 76 } 77 } 78 79 // 打点角色,它可以打点【备忘录】东西,如果是生存多个【备忘录】东西,固然可以对生存的东西进行增、删等打点措置惩罚惩罚---相当于【打点者角色】Caretaker 80 public sealed class MementoManager 81 { 82 //如果想生存多个【备忘录】东西,可以通过字典或者仓库来生存,仓库东西可以反应生存东西的先后挨次 83 //好比:public Dictionary<string, ContactPersonMemento> ContactPersonMementoDictionary { get; set; } 84 public ContactPersonMemento ContactPersonMemento { get; set; } 85 } 86 87 class Program 88 { 89 static void Main(string[] args) 90 { 91 List<ContactPerson> persons = new List<ContactPerson>() 92 { 93 new ContactPerson() { Name="黄飞鸿", MobileNumber = "13533332222"}, 94 new ContactPerson() { Name="方世玉", MobileNumber = "13966554433"}, 95 new ContactPerson() { Name="洪熙官", MobileNumber = "13198765544"} 96 }; 97 98 //手机名单倡议人 99 MobileBackOriginator mobileOriginator = new MobileBackOriginator(persons); 100 mobileOriginator.Show(); 101 102 // 创建备忘录并生存备忘录东西 103 MementoManager manager = new MementoManager(); 104 manager.ContactPersonMemento = mobileOriginator.CreateMemento(); 105 106 // 变动倡议人联系人列表 107 Console.WriteLine("----移除最后一个联系人--------"); 108 mobileOriginator.ContactPersonList.RemoveAt(2); 109 mobileOriginator.Show(); 110 111 // 恢复到原始状态 112 Console.WriteLine("-------恢复联系人列表------"); 113 mobileOriginator.RestoreMemento(manager.ContactPersonMemento); 114 mobileOriginator.Show(); 115 116 Console.Read(); 117 } 118 } 119 }
代码很简单,注释也很详细,不细说了。
温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/35096.html
- 上一篇:如果状态数值也相同就没意义了
- 下一篇:C#发送邮件代码