zoukankan      html  css  js  c++  java
  • 设计模式学习之备忘录模式(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其实就有这种影子。 

  • 相关阅读:
    input框和文字对齐问题
    滚动条位置判断
    【HDOJ】2007平方和与立方和
    POJ3177 Redundant Paths
    POJ3694 Network(tarjan求桥)
    UVA315 Network
    POJ1236 Network of schools
    ZOJ1008 Gnome Tetravex
    ZOJ007 Numerical Summation of a Series(纯数学)
    ZOJ1006 Do the Untwist
  • 原文地址:https://www.cnblogs.com/yxlblogs/p/4078478.html
Copyright © 2011-2022 走看看