• 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信息还原到前一状态。

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

  • 相关阅读:
    自定义swiper索引值的样式
    返回上一页面后页面后自动刷新(跨域也可)
    点击跳转到页面指定位置
    移动端输入框弹起影响布局(包括fixed布局情况)
    thinkPHP5模版页面volist循环offset使用
    Vue i18n国际化在实际项目中的使用
    前端Cookie、essionStorage、LocalStorage 的区别
    前端常用的一些浏览器对象
    前端取?后面的值
    前端下载文件重命名解决
  • 原文地址:https://www.cnblogs.com/Aries-rong/p/7873113.html
Copyright © 2020-2023  润新知