设计模式之------备忘录模式(Memento Pattern)

一、概念

①、什么是备忘录模式?

       在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

②、主要解决的问题?

       恢复原有数据

③、如何解决?

       通过一个备忘录类专门存储对象状态。

④、代码关键点?

       为了符合迪米特原则,需要增加一个管理备忘录的类;客户不与备忘录类耦合,与备忘录管理类耦合。

      迪米特原则:如果两个类不必彼此直接通信,那么这个两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的话,可以通过第三者转发这个调用。

⑤、应用实例?

       1、后悔药。 2、打游戏时的存档。 3、Windows 里的 ctri + z。 4、IE 中的后退。 4、数据库的事务管理。

⑥、优缺点?

优点: 1、给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。

            2、实现了信息的封装,使得用户不需要关心状态的保存细节。

缺点:消耗资源,如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。

⑦、使用场景?

      需要保存/恢复数据的相关状态场景;提供一个可回滚的操作。

二、图

①、结构图

②、拓展图

三、代码

①、代码类图

②、代码

客户端程序

 class Program
    {
        static void Main(string[] args)
        {
            //大战Big Mom 前
            GameRole lufei = new GameRole();                            //实例化一个游戏者角色:路飞
            lufei.GetInitState();                                       //调取游戏者方法:获取初始值
            lufei.StateDisplay();                                       //显示状态

            //保存进度
            RoleStateCaretaker stateAdmin = new RoleStateCaretaker();   //实例化一个角色状态管理者对象 stateAdmin
            stateAdmin.Menento = lufei.SaveState();                     //将保存的数据赋值给状态管理者的Menento属性

            //大战Big Mom时,损耗严重
            lufei.Fight();                                              //路飞开始战斗
            lufei.StateDisplay();                                       //显示战斗后的结果

            //恢复之前状态
            lufei.RecoveryState(stateAdmin.Menento);
            lufei.StateDisplay();
            Console.Read();
        }
    }

  发起人(Originator)类:游戏角色

class GameRole
    {
        #region 字段属性
        private int vit;
        public int Vitality
        {
            get { return vit; }
            set { vit = value; }
        }
        private int atk;
        public int Attack
        {
            get { return atk; }
            set { atk = value; }
        }
        private int def;
        public int Defense
        {
            get { return def; }
            set { def = value; }
        }
        #endregion

        //保存角色状态,创建一个备忘录
        public RoleStateMemento SaveState()                             //创建一个“保存角色状态"的方法,返回值类型为“角色状态存储箱”
        {
            return (new RoleStateMemento(vit, atk, def));               //将游戏角色的三个状态值, 通过实例化“角色状态存储箱”返回
        }
         //恢复之前状态
        public void RecoveryState(RoleStateMemento memento)  
        {
            this.vit = memento.Vitality;
            this.atk = memento.Attack;
            this.def = memento.Defense;
        }
        //状态显示
        public void StateDisplay()                                      //状态显示
        {
            Console.WriteLine("角色当前状态:");                               //显示游戏者的各种状态数据
            Console.WriteLine("体力:{0}", this.vit);
            Console.WriteLine("攻击力:{0}", this.atk);
            Console.WriteLine("防御力:{0}", this.def);
            Console.WriteLine("");
        }
        //获得初始状态
        public void GetInitState()                                      //游戏者获取初始值
        {
            this.vit = 100;                                             //体力:100
            this.atk = 100;                                             //攻击力:100
            this.def = 100;                                             //防御力:100
        }
        //战斗
        public void Fight()                                             //游戏者战斗
        {
            this.vit = 0;                                               //战斗后的值为0
            this.atk = 0;
            this.def = 0;
        }
    }

备忘录(Memento)类

 //备忘录类:角色状态存储箱类
    class RoleStateMemento
    {
        #region 存储箱字段属性
        private int vit;                                                //建立一个字段(字段一般采用私有修饰符)
        private int atk;
        private int def;
        public RoleStateMemento(int vit, int atk, int def)
        {
            this.vit = vit;
            this.atk = atk;
            this.def = def;
        }
        public int Vitality                                             //字段为私有的,仅当前类中可以使用,但还需要将字段值传出去,所以定义public属性
        {
            get { return vit; }
            set { vit = value; }
        }
        public int Attack
        {
            get { return atk; }
            set { atk = value; }
        }
        public int Defense
        {
            get { return def; }
            set { def = value; }
        }
        #endregion

    }

管理者(Caretaker)类

   class RoleStateCaretaker                                            //创建一个管理者类
    {
        private RoleStateMemento menento;                               //管理者类里建立一个存储箱字段
        public RoleStateMemento Menento                                 //一个存储箱属性
        {
            get { return menento; }
            set { menento = value; }
        }
    }

 注:在这里为什么要建立一个管理者类呢,此处体现了迪米特原则,把要保存的细节给封装在了Memonto中了,哪一天要更改保存的细节也不用影响客户端了。

四、拓展

属性与字段的区别?

属性是类提供给外部调用时用,的可以使用 对象.属性 设置或读取 一个值
get{reture xxx;}表示可读
set{xxx = value;}表示可写
字段就是类内部用的.存储数据

属性和字段最根本的区别是,属性是面向对象的范畴的对象,而字段是面向过程的范畴的对象。

https://www.cnblogs.com/lgx5/p/5351138.html

以上便是备忘录模式的简单梳理,下一站走起^_^

猜你喜欢

转载自blog.csdn.net/Elsa15/article/details/88225293
今日推荐