首页 > 代码库 > 设计模式学习之备忘录模式(Memento,行为型模式)(19)

设计模式学习之备忘录模式(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其实就有这种影子。 

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