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

时间: 2024-10-13 13:34:02

设计模式学习之备忘录模式(Memento,行为型模式)(19)的相关文章

设计模式学习之观察者模式(Observer,行为型模式)(7)

1.观察者模式又叫做发布-订阅模式. 2.观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 3.使用观察者模式的好处:维护相关对象间的一致性.我们不希望为了维持一致性而使各类紧密耦合,这样会给维护.扩展和重用都带来不便.什么时候使用观察者模式:当一个对象的改变需要同时改变其他对象的时候,而且它不知道具体有多少对象有待改变时,应该考虑使用观察者模式. private static void M

设计模式20:Memento 备忘录模式(行为型模式)

Memento 备忘录模式(行为型模式) 对象状态的回溯 对象状态的变化无端,如何回溯.恢复对象在某个点的状态? 动机(Motivation) 在软件构建过程中,某些对象的状态在转换过程中,可能由于某种需要,要求程序能够回溯到对象之前处于某个点时的状态.如果使用一些共有接口来让其他对象得到对象的状态,便会暴露对象的细节实现. 如何实现对象状态良好保存与恢复?同时又不会因而破坏对象本身的封装性. 意图(Intent) 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样

设计模式14:Command 命令模式(行为型模式)

Command 命令模式(行为型模式) 耦合与变化 耦合是软件不能抵御变化的根本性原因.不仅实体对象与实体对象之间存在耦合关系,实体对象与行为操作之间也存在耦合关系. 动机(Motivation) 在软件构建过程中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”.但在某些场合——比如对行为进行“记录.撤销/重做(undo/redo).事务”等处理,这种无法抵御变化的紧耦合是不合适的. 在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,可以实现二者之间的解耦. 意

设计模式19:Chain Of Responsibility 职责链模式(行为型模式)

Chain Of Responsibility 职责链模式(行为型模式) 请求的发送者与接受者 某些对象请求的接受者可能有多种多样,变化无常…… 动机(Motivation) 在软件构建过程中,一个请求可能被多个对象处理,但是每个请求在运行时只能有一个接受者,如果显示指定,将必不可少地带来请求发送者与接受者的紧耦合. 如何使请求的发送者不需要指定具体的接受者?让请求的接受者自己在运行时决定来处理请求,从而使两者解耦. 意图(Intent) 使多个对象都有机会处理请求,从而避免请求的发送者和接受者

设计模式22:Strategy 策略模式(行为型模式)

Strategy 策略模式(行为型模式) 动机(Motivation) 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂:而且有时候支持不使用的算法也是一个性能负担. 如何在运行时根据需要透明地更改算法?将算法与对象本身解耦,从而避免上述问题? 意图(Intent) 定义一系列算法,把它们一个个封装起来,并且使它们可以互相替换.该模式使得算法可以独立于使用它的客户而变化.——<设计模式>GoF 示例代码 enum CartType

设计模式23:Visitor 访问者模式(行为型模式)

Visitor 访问者模式(行为型模式) 动机(Motivation)在软件构造过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接在基类中做这样的修改,将会给子类带来繁重的变更负担,甚至破坏原有设计. 如果在不变更类层次结构的前提下,在运行时更加需要透明地为类层次结构上的各个类活动添加新的操作,从而避免上述问题? 意图(Intent) 表示一个作用于某种对象结构中各元素的操作.它可以在不改变各元素的类的前提下定义作用于这些元素的新操作.——<设计模式>GoF 示例代

设计模式21:State 状态模式(行为型模式)

State 状态模式(行为型模式) 动机(Motivation) 在软件构建过程中,某些对象的状态如果改变,其行为也会随之而发生变化,比如文档处于只读状态,其支持的行为和读写状态的行为就可能完全不同. 如何在运行时根据对象的状态来透明地更改对象的行为?而不会为对象操作和状态转换之间引入紧耦合? 意图(Intent) 允许一个对象在其内部状态改变时改变它的行为.从而使对象看起来似乎修改了其行为.——<设计模式>GoF 结构(Structure) 示例代码 public enum Document

设计模式17:Iterator 迭代器模式(行为型模式)

Iterator 迭代器模式(行为型模式) 动机(Motivation) 在软件构建过程中,集合对象内部结构常常变化各异.但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码可以透明地访问其包含的元素:同时这种“透明变量”也为“同一种算法在多种集合对象上进行操作”提供了可能. 使用面向对象技术使这种遍历机制抽象为“迭代器对象”为“应对变化中的集合对象”提供了一种优雅的方式. 意图(Intent)提供一种方法顺序访问一个聚合对象中各个元素 , 而又不需暴露该对象的内部表示.——

设计模式16:Mediator 中介者模式(行为型模式)

Mediator 中介者模式(行为型模式) 依赖关系的转化 动机(Motivation) 在软件构建过程中,经常出现多个对象互相关联交互的情况,对象之间经常会维持一种复杂的应用关系,如果遇到一些需求的更改,这种直接的引用将面临不断的变化. 在这种情况下,我们可以使用一个“中介对象”来管理对象间的关联关系,避免相互的对象之间的紧耦合引用关系,从而更好地抵御变化. 意图(Intent) 用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显示的相互引用,从而使其耦合松散,而且可以独立地改变它们

设计模式-04 建造者模式(创建型模式)

一 建造者模式 建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 主要解决:在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成:由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定. 关键代码 : 建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系. 使用场景: 汽车有很多部件,车轮