C#学习笔记-备忘录模式

什么是备忘录模式?

   备忘录模式(Memento):在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。

               这样以后就可将该对象恢复到原先保存的状态。 

备忘录模式的组成

    Originator(发起人):负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态。

            Originator可根据需要决定Memento存储Originator的哪些内部状态。

  Memento(备忘录):负责存储Originator对象的内部状态,并可防止Originator以外的其他对象访问Memento。

            Memento有两个接口,Caretaker只能看到备忘录的窄接口,它只能将备忘录传递给其他对象。

            Originator能够看到一个宽接口,允许它访问返回到现钱状态所需的所有数据。

  Caretaker(管理者):负责保存好备忘录Memento,不能对备忘录的内容进行操作或者检查。

备忘录模式具体实现

适配器模式的结构

  

适配器模式的实现

Originator(发起人)类:

 1     class Originator
 2         {
 3             private string state;
 4             public string State
 5             {
 6                 get { return state; }
 7                 set { state = value; }
 8             }
 9             public void Show()
10             {
11                 Console.WriteLine("State={0}", State);
12             }
13             /// <summary>
14             /// 从memento中调用之前保存好的参数
15             /// </summary>
16             public void SetMemento(Memento memento)
17             {
18                 this.state = memento.State;
19             }
20             /// <summary>
21             /// 将当前的参数记录到Memento中去
22             /// </summary>
23             /// <returns></returns>
24             public Memento CreateMemento()
25             {
26                 return (new Memento(state));
27             }
28         }

Memento(备忘录)类:

 1         class Memento
 2         {
 3             private string state;
 4             /// <summary>
 5             /// 备忘录中只需要变成只读就可以了
 6             /// </summary>
 7             public string State
 8             {
 9                 get { return state; }
10             }
11             public Memento(string state)
12             {
13                 this.state = state;
14             }
15         }

Caretaker(管理者)类:

1         class Caretaker
2         {
3             private Memento memento;
4             public Memento Memento
5             {
6                 get { return memento; }
7                 set { memento = value; }
8             }
9         }

主函数调用

 1         static void Main(string[] args)
 2         {
 3             //初始化Originator,设定初始数据
 4             Originator o = new Originator();
 5             o.State = "O";
 6             o.Show();
 7             //保存Originator传递至Memento中
 8             Caretaker c = new Caretaker();
 9             c.Memento = o.CreateMemento();
10             //修改Originator中的数据
11             o.State = "T";
12             o.Show();
13             //调用备忘录中数据,重新更新数据
14             o.SetMemento(c.Memento);
15             o.Show();
16 
17             Console.Read();
18         }

实例解析

   为了深化理解,我们准备一个具体的实例来分析。

   在玩游戏的过程中,假设游戏有99关,我们从第1关开始,打到第15关的时候没有成功,这是我们就需要保存保存当前的进度,不然下次进来的时候我们就又得从第一关重新开始了。

 分析:

  我们需要保存当前的进度,这只是起到一个暂存的作用。

  

具体实现:

  1     class Program
  2     {
  3         static void Main(string[] args)
  4         {
  5             //创建一个英雄角色李逍遥
  6             GameRole lixiaoyao = new GameRole();
  7             lixiaoyao.GetInitState();
  8             lixiaoyao.Show();
  9             //将李逍遥数据保存在备忘录中
 10             RoleStateCaretaker c = new RoleStateCaretaker();
 11             c.Menmento = lixiaoyao.SaveState();
 12             //让李逍遥参与战斗
 13             lixiaoyao.Fight();
 14             lixiaoyao.Show();
 15             //由于参与战斗后状态都发生了变化,所以重新调用以前的数据
 16             lixiaoyao.RecoverState(c.Menmento);
 17             lixiaoyao.Show();
 18 
 19             Console.Read();
 20         }
 21         class GameRole
 22         {
 23             private int vitality;
 24             private int attack;
 25             private int defense;
 26             //生命力
 27             public int Vitality
 28             {
 29                 get { return vitality; }
 30                 set { vitality = value; }
 31             }
 32             //攻击力
 33             public int Attack
 34             {
 35                 get { return attack; }
 36                 set { attack = value; }
 37             }
 38             //防御力
 39             public int Defense
 40             {
 41                 get { return defense; }
 42                 set { defense = value; }
 43             }
 44             //获取初始状态
 45             public void GetInitState()
 46             {
 47                 this.vitality = 100;
 48                 this.defense = 100;
 49                 this.attack = 100;
 50             }
 51             //从Memento中获取到刚刚保存的数据
 52             public void RecoverState(RoleStateMemento memento)
 53             {
 54                 this.vitality = memento.Vitality;
 55                 this.defense = memento.Defense;
 56                 this.attack = memento.Attack;
 57             }
 58             //保存当前数据到Memento中
 59             public RoleStateMemento SaveState()
 60             {
 61                 return (new RoleStateMemento(vitality, attack, defense));
 62             }
 63             //显示当前状态
 64             public void Show()
 65             {
 66                 Console.WriteLine("State:");
 67                 Console.WriteLine("vitality={0}", vitality);
 68                 Console.WriteLine("Attack={0}", attack);
 69                 Console.WriteLine("Defense={0}", Defense);
 70             }
 71             //参与战队导致状态变得不好了
 72             public void Fight()
 73             {
 74                 this.vitality = 0;
 75                 this.attack = 0;
 76                 this.defense = 0;
 77             }
 78         }
 79         class RoleStateMemento
 80         {
 81             private int vitality;
 82             private int attack;
 83             private int defense;
 84             //生命力
 85             public int Vitality
 86             {
 87                 get { return vitality; }
 88                 set { vitality = value; }
 89             }
 90             //攻击力
 91             public int Attack
 92             {
 93                 get { return attack; }
 94                 set { attack = value; }
 95             }
 96             //防御力
 97             public int Defense
 98             {
 99                 get { return defense; }
100                 set { defense = value; }
101             }
102             //当角色将数据传递过来的时候需要调用这个函数
103             public RoleStateMemento(int v,int a,int d)
104             {
105                 this.vitality = v;
106                 this.defense = d;
107                 this.attack = a;
108             }
109         }
110         class RoleStateCaretaker
111         {
112             private RoleStateMemento memento;
113             public RoleStateMemento Menmento
114             {
115                 get { return memento; }
116                 set { memento = value; }
117             }
118         }
119     }

备忘录模式的优缺点

   Memento模式比较适用于功能比较复杂的,但是需要维护或者记录属性历史的类,或者需要保存的属性只是众多属性中的一个小部分时。Originator可以根据保存的Memento信息还原到前一状态。

 

 

备注:文中所有代码及知识点均来自于《大话设计模式》,本人属于边学边看边敲代码边总结的阶段。

posted @ 2017-11-21 14:49  多多陪着小五  阅读(374)  评论(0编辑  收藏  举报