//---------------------------15/04/27----------------------------

//Memento 备忘录模式----对象行为型模式

/*

1:意图:

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可讲该对象

恢复到原先保存的状态。

2:别名:

Token

3:动机:

4:适用性:

1>必须保存一个对象在某一个时刻的状态,这样以后需要时它才能恢复到先前的状态。

2>如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。

5:结构:

Caretaker:

Originator:- - - - - - - - >Memento:<---------memento

SetMemento(Memento m)       GetState()

{ state = m->GetState()}    SetState()

CreateMemento()             state

{ retrun new Memento(state)}

state

6:参与者:

1>Memento:

1)备忘录存储原发器的内部状态。原发器根据需要决定备忘录存储原发器的哪些内部状态。

2)防止原发器以外的其他对象访问备忘录。备忘录实际上有两个接口,管理者接口只能看到备忘录的窄

接口--它只能讲备忘录传递给其他对象。相反,原发器能看到一个宽接口,允许它访问返回到先前状态

所需的所有数据。

2>Originator

1)原发器创建一个备忘录,用以纪录当前时刻它的内部状态。

2)使用备忘录恢复内部状态。

3>Caretaker

1)负责保存好备忘录。

2)不能对备忘录的内容进行操作或检查。

7:协作:

1>管理器向原发器请求一个备忘录,保存一段时间后,将其送回原发器。

2>备忘录时被动的。只有创建备忘录的原发器会对他的状态进行赋值和检索。

8:效果:

1>优点:

1)保护封装边界:

使用备忘录可以避免暴露一些只应由原发器管理却又必须存储在原发器之外的信息。

2)简化了原发器:

让客户来管理它们请求的状态会简化原发器,并且似的客户工作结束时无需通知原发器。

2>缺点:

1)使用备忘录可能代价很高:

如果原发器在生产备忘录时必须拷贝并存储大量的信息,或者客户非常频繁地创建备忘录和恢复原发器

状态,可能会导致非常大的开销。

2)维护备忘录的潜在代价:

管理器负责删除它所维护的备忘录,然后管理器不知道备忘录中有多少个状态。因此当存储备忘录时,

一个本来很小的管理器,可能会产生大量的存储开销。

3>定义窄接口和宽接口:

在一些语言中可能难以保证只有原发器可以访问备忘录的状态。

9:实现:

1>语言支持:

备忘录有两个接口:一个为原发器所使用的宽接口,一个为其他对象所使用的窄接口。

在c++可以声明Originator为Memento的一个友元,并使用Memento宽接口为私有的,把窄接口声明为公有。

2>存储增量式改变:

如果备忘录的创建及其返回的顺序是可预测的,备忘录可以仅存储原发器内部状态的增量改变。

10:代码示例:                                                                            */

class Graphic;

//Caretaker,提供操作

class MoveCommand

{

public:

MoveCommand(Graphic* target,
const Point& delta);

void Execute();

void Unexecute();

private:

ConstraintSolverMemento* _state;

Point _delta;

Graphic* _target;

};

//原发器:提供创建,保存,撤销操作

class ConstraintSolver

{

public:

static ConstraintSolver* Instance();

void Solve();

void AddConstraint(Graphic* startConnection, Graphic* endConnection);

void RemoveConstaint(Graphic* startConnection, Graphic* endConnection);

ConstraintSolverMemento* CreateMemento();

void SetMemento(ConstraintSolverMemento*);

private:

};

//备忘录

class ConstraintSolverMemento

{

public:

virtual ~ConstraintSolverMemento();

private:

friend class ConstraintSolver;

ConstraintSolverMemento();

//...还有一些state

};

//使用原发器创建一个备忘录,保存起来,然后做别的操作

void MoveCommand::Execute()

{

ConstraintSolver* solver = ConstraintSolver::Instance();

_state = solver->CreateMemento();

_target->Move(_delta_);

solver->Solve();

}

//使用之前存储的备忘录来恢复之前的状态。

void MoveCommand::Unexecute()

{

ConstraintSolver* solver = ConstraintSolver::Instance();

_target->Move(-_delta);

solver->SetMemento(_state);

solver->Solve();

}

//这个例子没法恢复两次以上状态,如果要恢复两次以上,必须使用数组或链表把一个个备忘录存储起来。

设计模式 笔记 备忘录模式 Memento的更多相关文章

  1. 乐在其中设计模式(C#) - 备忘录模式(Memento Pattern)

    原文:乐在其中设计模式(C#) - 备忘录模式(Memento Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 备忘录模式(Memento Pattern) 作者:webabc ...

  2. 设计模式之备忘录模式(Memento)

    备忘录模式(Memento) 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. Originator(发起人):负责创建一个备忘录 ...

  3. 二十四种设计模式:备忘录模式(Memento Pattern)

    备忘录模式(Memento Pattern) 介绍在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到保存的状态. 示例有一个Message实体类,某 ...

  4. 【设计模式】—— 备忘录模式Memento

    前言:[模式总览]——————————by xingoo 模式意图 这个模式主要是想通过一个对象来记录对象的某种状态,这样有利于在其他需要的场合进行恢复. 该模式还有跟多可以扩展的地方,比如可以记录多 ...

  5. [设计模式] 18 备忘录模式Memento Pattern

    在GOF的<设计模式:可复用面向对象软件的基础>一书中对备忘录模式是这样说的:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存 ...

  6. 学习笔记——备忘录模式Memento

    备忘录模式,可以将当前状态保存,并随时恢复. Originator存在状态state,当需要保存此状态时,通过CreateMemento创建一个备忘录对象Memento保存此状态:而需要恢复相应状态时 ...

  7. 行为型设计模式之备忘录模式(Memento)

    结构 意图 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. 适用性 必须保存一个对象在某一个时刻的(部分)状态, 这样以后需要时 ...

  8. 再起航,我的学习笔记之JavaScript设计模式24(备忘录模式)

    备忘录模式 概念介绍 备忘录模式(Memento): 在不破坏对象的封装性的前提下,在对象之外捕获并保存该对象内部的状态以便日后对象使用或者对象恢复到以前的某个状态. 简易分页 在一般情况下我们需要做 ...

  9. 备忘录模式 Memento 快照模式 标记Token模式 行为型 设计模式(二十二)

    备忘录模式 Memento   沿着脚印,走过你来时的路,回到原点.     苦海翻起爱恨   在世间难逃避命运   相亲竟不可接近   或我应该相信是缘份   一首<一生所爱>触动了多少 ...

随机推荐

  1. 《SQL Server 2008从入门到精通》--20180724

    目录 1.事务 1.1.事务的ACID属性 1.2.事务分类 1.2.1.系统提供的事务 1.2.2.用户自定义的事务 1.3.管理事务 1.3.1.SAVE TRANSACTION 1.3.2.@@ ...

  2. 客户端连接caching-sha2-password问题

    ALTER USER 'root'@'localhost' IDENTIFIED BY '123' PASSWORD EXPIRE NEVER;ALTER USER 'root'@'localhost ...

  3. skype客户端搜不到联系人解决办法

    1.确认skype客户端登陆的配置信息 按住Ctrl 键不放,右击右下角任务栏 skype 图标,选择:配置信息,确认skype的:GAL搜索或基于服务器的搜索为:基于服务器的搜索,如下图所示: 2. ...

  4. ubuntu各类问题笔记

    ubuntu文本编辑器中文中文乱码问题解决 转载自:http://www.2cto.com/os/201201/117535.html 缺省配置下,用Ubuntu 的文本编辑器(gedit)打开GB1 ...

  5. ArcGIS Earth1.9最新版安装和使用教程

    1.下载ArcGIS Earth 官网下载地址:https://www.esri.com/en-us/arcgis/products/arcgis-earth 在这个网页的最下面填上信息,就可以下载了 ...

  6. Windows Server 2008远程桌面端口更改方法

    win2008远程桌面端口默认是用的是3389端口,但是由于安全考虑,经常我们安装好系统后一般都会考虑把原来的3389端口更改为另外的端口.本文以改为端口为25608商品为例,讲解一下具体操作过程. ...

  7. ES6对抽象工厂模式与策略模式结合的实践

    这段代码是我在学习了java版的抽象工厂模式后,实现的ES6版抽象工厂,后期大幅修改,加入了策略模式,看起来很多逻辑看似繁琐,不必要写这么多,但是为了练习设计模式,所以才这样做.当所需的工厂种类增多后 ...

  8. BZOJ2815:[ZJOI2012]灾难(拓扑排序,LCA)

    Description 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难. 学过 ...

  9. node.js cheerio API

    安装 npm install cheerio load var cheerio = require('cheerio'), $ = cheerio.load('<ul id=“fruits”&g ...

  10. php 数据集转换树、递归重组节点信息多维数组(转)

    一.将数据集转换成树 /** * 将返回的数据集转换成树 * @param array $list 数据集 * @param string $pk 主键 * @param string $pid 父节 ...