• 设计模式学习之备忘录模式(Memento,行为型模式)(19)


    假如我们已经记录一个人的个人信息,但是发现信息写错了,然后我先备份下再去修改,结果发现原来的信息是正确的,于是我就看备份的个人信息还原到初始的状态,下面我们用代码去实现

    class Program
        {
            static void Main(string[] args)
            {
                Person person = new Person("张三", "", 25);
            
                //保存内部状态
                Person personBackup = new Person();
                personBackup.Name = person.Name;
                personBackup.Gender = person.Gender;
                personBackup.Age = person.Age;
                person.Show();
                //修改
                person.Name = "李四";
                person.Gender = "";
                person.Age = 20;
                person.Show();
                //回滚还原
                person.Name = personBackup.Name;
                person.Gender = personBackup.Gender;
                person.Age = personBackup.Age;
                person.Show();
    
            }
        }
    
        public class Person
        {
            public string Name { get; set; }
            public string Gender { get; set; }
            public int Age { get; set; }
    
            public Person()
            {
                
            }
            public Person(string name,string gender,int age)
            {
                this.Name = name;
                this.Gender = gender;
                this.Age = age;
            }
    
            public void Show()
            {
                Console.WriteLine("姓名:{0},性别:{1},年龄:{2}",Name,Gender,Age);
            }
    
           
        }

    运行结果:

    虽然功能实现了但是Main函数中要做的事情太多了,违反了类的单一职责原则,下面我们使用备忘录模式来实现

     internal class Program
        {
            private static void Main(string[] args)
            {
                Person person = new Person("张三", "", 25);
    
                //保存内部状态
                Memento memento = person.CreateMemento();
                person.Show();
                //修改
                person.Name = "李四";
                person.Gender = "";
                person.Age = 20;
                person.Show();
                //回滚还原
                person.SetMemento(memento);
                person.Show();
            }
        }
    
        public class Person
        {
            public string Name { get; set; }
            public string Gender { get; set; }
            public int Age { get; set; }
    
            public Person()
            {
    
            }
            public Person(string name, string gender, int age)
            {
                this.Name = name;
                this.Gender = gender;
                this.Age = age;
            }
    
            public void Show()
            {
                Console.WriteLine("姓名:{0},性别:{1},年龄:{2}", Name, Gender, Age);
            }
    
            /// <summary>
            /// 创建一个备份
            /// </summary>
            /// <returns></returns>
            public Memento CreateMemento()
            {
                return new Memento(Name, Gender, Age);
            }
    
            /// <summary>
            /// 恢复备份
            /// </summary>
            /// <param name="memento">备份的对象</param>
            public void SetMemento(Memento memento)
            {
                this.Name = memento.Name;
                this.Gender = memento.Gender;
                this.Age = memento.Age;
            }
    
        }
    
        public class Memento
        {
            public string Name { get; set; }
            public string Gender { get; set; }
            public int Age { get; set; }
    
            public Memento()
            {
    
            }
            public Memento(string name, string gender, int age)
            {
                this.Name = name;
                this.Gender = gender;
                this.Age = age;
            }
        }

    此时我们通过Person来创建Memento对象来保存Person信息,如果备忘录的东西比较多的话,我们可以通过一个管理者对象Caretaker来管理备忘录对象,改造代码如下:

    internal class Program
        {
            private static void Main(string[] args)
            {
                Person person = new Person("张三", "", 25);
    
                //保存内部状态
                Caretaker caretaker = new Caretaker();
                caretaker.Memento = person.CreateMemento();
                person.Show();
                //修改
                person.Name = "李四";
                person.Gender = "";
                person.Age = 20;
                person.Show();
                //回滚还原
                person.SetMemento(caretaker.Memento);
                person.Show();
            }
        }
    
        /// <summary>
        /// 原生者
        /// </summary>
        public class Person
        {
            public string Name { get; set; }
            public string Gender { get; set; }
            public int Age { get; set; }
    
            public Person()
            {
    
            }
            public Person(string name, string gender, int age)
            {
                this.Name = name;
                this.Gender = gender;
                this.Age = age;
            }
    
            public void Show()
            {
                Console.WriteLine("姓名:{0},性别:{1},年龄:{2}", Name, Gender, Age);
            }
    
            /// <summary>
            /// 创建一个备份
            /// </summary>
            /// <returns></returns>
            public Memento CreateMemento()
            {
                return new Memento(Name, Gender, Age);
            }
    
            /// <summary>
            /// 恢复备份
            /// </summary>
            /// <param name="memento">备份的对象</param>
            public void SetMemento(Memento memento)
            {
                this.Name = memento.Name;
                this.Gender = memento.Gender;
                this.Age = memento.Age;
            }
    
        }
    
        /// <summary>
        /// 备忘录
        /// </summary>
        public class Memento
        {
            public string Name { get; set; }
            public string Gender { get; set; }
            public int Age { get; set; }
    
            public Memento()
            {
    
            }
            public Memento(string name, string gender, int age)
            {
                this.Name = name;
                this.Gender = gender;
                this.Age = age;
            }
        }
    
        /// <summary>
        /// 管理者
        /// </summary>
        public class Caretaker
        {
            public Memento Memento { get; set; }
        } 

    一、什么是备忘录模式
    Memento模式也叫做备忘录模式,是行为型模式的一种,它的作用是保存对象的内部状态,并在需要的时候(undo/rollback)恢复对象以前的状态。
    二、备忘录模式的应用场景
    如果一个对象需要保存状态并可通过undo或rollback等操作恢复到以前的状态时,可以使用Memento模式。
    在实际应用中,备忘录模式都是多状态和多备份的,原生者角色的状态需要存储到备忘录对象中,对资源的消耗是比较严重的。
    (1)一个类需要保存它的对象的状态(相当于Originator角色)
    (2)设计一个类,该类只是用来保存上述对象的状态(相当于Memento角色)
    (3)需要的时候,Caretaker角色要求Originator返回一个Memento并加以保存
    (4)undo或rollback操作时,通过Caretaker保存的Memento恢复Originator对象的状态
    三、备忘录模式的角色和职责
    Originator(原生者)
    需要被保存状态以便恢复的那个对象
    Memento(备忘录)
    该对象由Originator创建,主要用来保存Originator对象的状态。其实这个和克隆很相似,只不过是克隆出来的对象可以拥有对象的接口,而Memento没有。Memento只封装状态,而不再提供其它操作。
    Caretaker(管理者)
    负责在适当的时间保存/恢复Origniator对象的状态

    四、.net中备忘录模式

    我们也可以用序列化的方式实现备忘录。序列化之后,我们可以把它临时性保存到数据库、文件、进程内、进程外等地方。ASP.Net的Session其实就有这种影子。 

  • 相关阅读:
    CodeForces 660D Number of Parallelograms
    【POJ 1082】 Calendar Game
    【POJ 2352】 Stars
    【POJ 2481】 Cows
    【POJ 1733】 Parity Game
    【NOI 2002】 银河英雄传说
    【NOI 2015】 程序自动分析
    【POJ 1704】 Georgia and Bob
    【HDU 2176】 取(m堆)石子游戏
    【SDOI 2016】 排列计数
  • 原文地址:https://www.cnblogs.com/yxlblogs/p/4078478.html
Copyright © 2020-2023  润新知