设计模式学习之备忘录模式(Memento,行为型模式)(19)
假如我们已经记录一个人的个人信息,但是发现信息写错了,然后我先备份下再去修改,结果发现原来的信息是正确的,于是我就看备份的个人信息还原到初始的状态,下面我们用代码去实现
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)的更多相关文章
- 设计模式学习之单例模式(Singleton,创建型模式)(4)
假如程序中有一个Person类,我的需求就是需要在整个应用程序中只能new一个Person,而且这个Person实例在应用程序中进行共享,那么我们该如何实现呢? 第一步: 新建一个Person类,类中 ...
- 设计模式学习之观察者模式(Observer,行为型模式)(7)
1.观察者模式又叫做发布-订阅模式. 2.观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 3 ...
- 设计模式20:Memento 备忘录模式(行为型模式)
Memento 备忘录模式(行为型模式) 对象状态的回溯 对象状态的变化无端,如何回溯.恢复对象在某个点的状态? 动机(Motivation) 在软件构建过程中,某些对象的状态在转换过程中,可能由于某 ...
- 设计模式17:Iterator 迭代器模式(行为型模式)
Iterator 迭代器模式(行为型模式) 动机(Motivation) 在软件构建过程中,集合对象内部结构常常变化各异.但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码可以透 ...
- 设计模式16:Mediator 中介者模式(行为型模式)
Mediator 中介者模式(行为型模式) 依赖关系的转化 动机(Motivation) 在软件构建过程中,经常出现多个对象互相关联交互的情况,对象之间经常会维持一种复杂的应用关系,如果遇到一些需求的 ...
- 设计模式23:Visitor 访问者模式(行为型模式)
Visitor 访问者模式(行为型模式) 动机(Motivation)在软件构造过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接在基类中做这样的修改,将会给子类带来繁重的 ...
- 设计模式22:Strategy 策略模式(行为型模式)
Strategy 策略模式(行为型模式) 动机(Motivation) 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂:而且有时候支持 ...
- 设计模式21:State 状态模式(行为型模式)
State 状态模式(行为型模式) 动机(Motivation) 在软件构建过程中,某些对象的状态如果改变,其行为也会随之而发生变化,比如文档处于只读状态,其支持的行为和读写状态的行为就可能完全不同. ...
- 设计模式19:Chain Of Responsibility 职责链模式(行为型模式)
Chain Of Responsibility 职责链模式(行为型模式) 请求的发送者与接受者 某些对象请求的接受者可能有多种多样,变化无常…… 动机(Motivation) 在软件构建过程中,一个请 ...
- 设计模式15:Interpreter 解释器模式(行为型模式)
Interpreter 解释器模式(行为型模式) 动机(Motivation) 在软件构建过程中,如果某一特定领域的问题比较复杂,类似的模式不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变 ...
随机推荐
- Sqli-LABS通关笔录-12
通过这个关卡我学习到了: 1.双引号千万别忘记,就是因为忘了弄了好一会儿.一直不报错. 2. 00x1万能密码构造二 报错的内容为: You have an error in your SQL syn ...
- eclipse中整合springMvc,velocity和sitemesh
1.项目所需要jar包 (有些可能多余) 2.创建UserController 目录如下: package qust.thb.usermanage.controller; import org.s ...
- SPOJ 1811 Longest Common Substring
Description 给出两个字符串,求最长公共子串. Sol SAM. 这题随便做啊...后缀数组/Hash+二分都可以. SAM就是模板啊...直接在SAM上跑就行,没有了 \(go[w]\) ...
- Linux中的动态库和静态库(.a/.la/.so/.o)
Linux中的动态库和静态库(.a/.la/.so/.o) Linux中的动态库和静态库(.a/.la/.so/.o) C/C++程序编译的过程 .o文件(目标文件) 创建atoi.o 使用atoi. ...
- Python自动化之多进程
多进程multiprocessing from multiprocessing import Process import os def info(title): print(title) print ...
- Python 2.x闭包(enclosure)中的变量访问&修改
http://stackoverflow.com/questions/3190706/nonlocal-keyword-in-python-2-x ---answer---- Python can r ...
- [ruby on rails] 深入(1) ROR的一次request的响应过程
示意图 即: 1. 浏览器发起请求 2. Routes对请求进行一个url映射,交给对应的Controller来处理 3/4. Contoller从Model中获取数据(或者操作数据) 5. 返回给 ...
- NUI控件扩展
摘要:NUI组件是公司新一代的前端开发框架,它精致优雅的前端编程模型,是大家能够,或者想接受学习它的重要原因,在使用它的时候,一定不免会想增加自己的控件,让别人也能够如此优雅的使用. 其实NUI的扩展 ...
- CEF3开发者系列之进程和线程
CEF3是一个多进程架构框架,如果有了解过chromium的进程架构的,那么就很容易了解CEF3的多进程了.打开CEF3源代码中发布的cefclient实例,如果打开的页面带有flash或者其他插件. ...
- Delphi xe5 手机开发经验(新手级别)
Delphi xe5 手机开发经验(新手级别) http://diybbs.zol.com.cn/1/34037_699.html http://www.delphitop.com/html/jiqi ...