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

class Program
{
static void Main(string[] args)
{
Person person = new Person("张三", "男", ); //保存内部状态
Person personBackup = new Person();
personBackup.Name = person.Name;
personBackup.Gender = person.Gender;
personBackup.Age = person.Age;
person.Show();
//修改
person.Name = "李四";
person.Gender = "女";
person.Age = ;
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("张三", "男", ); //保存内部状态
Memento memento = person.CreateMemento();
person.Show();
//修改
person.Name = "李四";
person.Gender = "女";
person.Age = ;
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("张三", "男", ); //保存内部状态
Caretaker caretaker = new Caretaker();
caretaker.Memento = person.CreateMemento();
person.Show();
//修改
person.Name = "李四";
person.Gender = "女";
person.Age = ;
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)的更多相关文章

  1. 设计模式学习之单例模式(Singleton,创建型模式)(4)

    假如程序中有一个Person类,我的需求就是需要在整个应用程序中只能new一个Person,而且这个Person实例在应用程序中进行共享,那么我们该如何实现呢? 第一步: 新建一个Person类,类中 ...

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

    1.观察者模式又叫做发布-订阅模式. 2.观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 3 ...

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

    Memento 备忘录模式(行为型模式) 对象状态的回溯 对象状态的变化无端,如何回溯.恢复对象在某个点的状态? 动机(Motivation) 在软件构建过程中,某些对象的状态在转换过程中,可能由于某 ...

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

    Iterator 迭代器模式(行为型模式) 动机(Motivation) 在软件构建过程中,集合对象内部结构常常变化各异.但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码可以透 ...

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

    Mediator 中介者模式(行为型模式) 依赖关系的转化 动机(Motivation) 在软件构建过程中,经常出现多个对象互相关联交互的情况,对象之间经常会维持一种复杂的应用关系,如果遇到一些需求的 ...

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

    Visitor 访问者模式(行为型模式) 动机(Motivation)在软件构造过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接在基类中做这样的修改,将会给子类带来繁重的 ...

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

    Strategy 策略模式(行为型模式) 动机(Motivation) 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂:而且有时候支持 ...

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

    State 状态模式(行为型模式) 动机(Motivation) 在软件构建过程中,某些对象的状态如果改变,其行为也会随之而发生变化,比如文档处于只读状态,其支持的行为和读写状态的行为就可能完全不同. ...

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

    Chain Of Responsibility 职责链模式(行为型模式) 请求的发送者与接受者 某些对象请求的接受者可能有多种多样,变化无常…… 动机(Motivation) 在软件构建过程中,一个请 ...

  10. 设计模式15:Interpreter 解释器模式(行为型模式)

    Interpreter 解释器模式(行为型模式) 动机(Motivation) 在软件构建过程中,如果某一特定领域的问题比较复杂,类似的模式不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变 ...

随机推荐

  1. 解决vista和win7在windows服务中交互桌面权限问题:穿透Session 0 隔离

        在某国外大型汽车公司BI项目中,有一个子项目,需要通过大屏幕展示销售报表,程序需要自动启动和关闭.开发人员在开发过程中,发现在Win7的service中不能直接操作UI进程,调查过程中,发现如 ...

  2. httpclient+Jsoup总结

    Jsoup.parse解析HTML字符串,如Jsoup.parse("<html><head><title>Firstparse</title> ...

  3. [大坑]FFT学习

    [大坑]FFT学习 Macros #define fon(i,s) for(int i=0;i<s; ++i) #define fone(i,s) for(int i=0;i<=s;++i ...

  4. VirtualBox中安装Ubuntu12.04/Ubuntu14.04虚拟机

    NOTE: 一开始安装的Ubuntu12.04,后来又重新安装了14.04.截图基本使用了安装12.04时的截图,后来安装14.04时又补充了几张.该安装过程对Ubuntu12.04和14.04都是适 ...

  5. C# nullable<T> 用法小结

    今天在园子里看到一个关于C#中对于可空类型的描述的帖子,感觉不错于是自己写了个小例子尝试下. 在C#中,对于可空类型描述为:Nullable<T>, 它表示该类型是可以为空的一个类型.它被 ...

  6. Isomorphic Strings

    Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the chara ...

  7. Best Time to Buy and Sell Stock with Cooldown

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  8. ODATA 云驱动 http://www.cdata.com/cloud/

    ODATA 云驱动   http://www.cdata.com/cloud/    目前支持:ORACLE.MS SQL . MYSQL. -------------- rssbus      ht ...

  9. dump、cpio、tar、dd四种备份工具比较

    原文  http://blog.csdn.net/ether_lai/article/details/12656219 dump dump可执行文件系统增量备份的存储操作 ,dump 可将目录或整个文 ...

  10. Delphi Excel 操作大全

    Delphi Excel 操作大全 (一) 使用动态创建的方法首先创建 Excel 对象,使用ComObj:var ExcelApp: Variant;ExcelApp := CreateOleObj ...