//---------------------------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. 在 Azure 中创建通用 VM 的托管映像

    可以从在存储帐户中存储为托管磁盘或非托管磁盘的通用 VM 中创建托管映像资源. 然后可以使用该映像创建多个 VM. 使用 Sysprep 通用化 Windows VM Sysprep 将删除所有个人帐 ...

  2. Sql server bulk insert

    Bulk Insert Sql server 的bulk insert语句可以高效的导入大数据量的平面文件(txt,csv文件)到数据库的一张表中,其用法如下: bulk insert test fr ...

  3. 纯Css实现Div高度根据自适应宽度(百分比)调整

    在如今响应式布局的要求下,很多能自动调整尺寸的元素能够做到高宽自适应,如img,通过{width:50%;height:auto;}实现图片高度跟随宽度比例调整. 然而,用的最多的标签一哥Div却不能 ...

  4. .net 页面传参方式总结

    一.使用Querystring Querystring是一种非常简单的传值方式,其缺点就是:安全性低.会把要传送的值显示在浏览器的地址栏中(也就是不需要保密得参数),并且在此方法中不能够传递对象,参数 ...

  5. python基础学习15----异常处理

    异常处理,是编程语言或计算机硬件里的一种机制,用于处理软件或信息系统中出现的异常状况(即超出程序正常执行流程的某些特殊条件). 1.异常的类型 异常的类型多种多样,常见的异常有: AttributeE ...

  6. security/pam_appl.h:没有那个文件或目录

    在编译开源库时, 提示 pam.h:4:10: 致命错误:security/pam_appl.h:没有那个文件或目录 #include <security/pam_appl.h> 解决方法 ...

  7. selenium-百度搜索框输入后,定位联想下拉框元素

    1.输入关键字后,显示联想下拉框,鼠标右键对应的联想字段,点击检查,就可在F12模式下元素查看器中定位到,之后使用Xpath定位.

  8. It was not possible to find any compatible framework version

    It was not possible to find any compatible framework version The specified framework 'Microsoft.NETC ...

  9. windows系统显示隐藏文件以及显示文件扩展名

    1.XP系统 打开“我的电脑”,“工具”,“文件夹选项” 勾选如下图 2.win7系统 打开“计算机”,“组织”,“文件夹和搜索选项” 勾选如下图 3.win10系统 打开“此电脑”,“查看”,勾选如 ...

  10. Django商城项目笔记No.2项目准备工作

    Django商城项目笔记No.2项目准备工作 接着上篇开始,创建好工程之后,随之而来的是怎么配置工程,这篇文章记录如何进行相关的配置 1.pycharm打开工程,进行相关的配置 通过pycharm打开 ...