设计模式学习之备忘录模式(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) 在软件构建过程中,如果某一特定领域的问题比较复杂,类似的模式不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变 ...
随机推荐
- html5跨域通讯之postMessage的用法
转自:http://www.cnblogs.com/wshiqtb/p/3171199.html postMessagePortal.html 页面代码 <!DOCTYPE html> & ...
- React JS快速入门教程
翻译至官方文档<Tutorial>http://facebook.github.io/react/docs/tutorial.html 转载请注明出处:http://blog.csdn.n ...
- Google Code Jam 2015 R2 C
题意:给出若干个句子,每个句子包含多个单词.确定第一句是英文,第二句是法文.后面的句子两者都有可能.两个语种会有重复单词. 现在要找出一种分配方法(给每个句子指定其文种),使得既是英文也是法文的单词数 ...
- string literals may have at most 255 elements
一行中的字符超出 255 时候发生这个错误 解决方式: 一行的字符串分成两行 并 + 连接 **** 将字符串分成两个用"+"连接起来
- python2.79安装
从官网下载最新的安装程序,基于windows的,也可以直接百度下载 点击安装,如果其他用户不需要python的话,可以使用第二个,不过我们一般都是单用户,所以没差 选择安装路径,可按默认路径安装,也可 ...
- codevs 3290 华容道(SPFA+bfs)
codevs 3290华容道 3290 华容道 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 小 B 最近迷上了华容道,可是 ...
- HDU 5878 I Count Two Three (打表+二分查找) -2016 ICPC 青岛赛区网络赛
题目链接 题意:给定一个数n,求大于n的第一个只包含2357四个因子的数(但是不能不包含其中任意一种),求这个数. 题解:打表+二分即可. #include <iostream> #inc ...
- POJ 3185 The Water Bowls (高斯消元)
题目链接 题意:翻译过来就是20个0或1的开关,每次可以改变相邻三个的状态,问最小改变多少次使得所有开关都置为0,题目保证此题有解. 题解:因为一定有解,所以我们可以正序逆序遍历两次求出较小值即可.当 ...
- [页面滚动到底部]jquery $(window).height()取值等于$(document).height()的问题
问题现象:JSP中头部引用了某个head.jsp,在videoList.jsp中生成片段时如下 实际最终生成的HTML如下: <!DOCTYPE html>没有解析到,原因找到了,先想办法 ...
- Sql如何自动定时备份数据库
直接上图