//---------------------------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 2012 列存储索引分析(转载)

    一.概述 列存储索引是SQL Server 2012中为提高数据查询的性能而引入的一个新特性,顾名思义,数据以列的方式存储在页中,不同于聚集索引.非聚集索引及堆表等以行为单位的方式存储.因为它并不要求 ...

  2. 转:HttpModule与HttpHandler详解

    ASP.NET对请求处理的过程:当请求一个*.aspx文件的时候,这个请求会被inetinfo.exe进程截获,它判断文件的后缀(aspx)之后,将这个请求转交给 ASPNET_ISAPI.dll,A ...

  3. web导出excel文件的几种方法

    总的来说,两种方法:服务器端生成和浏览器端生成. 服务器端生成就是:根据用户请求,获取相应的数据,使用poi/jxl, jacob/jawin+excel,或是用数据拼html的table或是cvs纯 ...

  4. 转:winform 打包自动安装数据库

    vs2005 打包,并自动安装SQL数据库.创建部署项目    1.   在“文件”菜单上指向“添加项目”,然后选择“新建项目”.    2.   在“添加新项目”对话框中,选择“项目类型”窗格中的“ ...

  5. 【存在问题,待修改】SSH 远程登陆

    0. 前提 设置 hosts 参考链接 Linux 配置 hosts SSH公钥登录原理 1. SSH 是什么 SSH ( Secure Shell ) 是一种协议标准,其目的是实现安全远程登录以及其 ...

  6. python第二十九课——文件读写(写数据的操作)

    演示写数据的操作: 结论:往文件中写入数据,如果文件不存在,先创建文件,再写入内容 #1.打开文件 fw=open(r'd.txt','w',encoding='utf-8') #2.写数据操作 fw ...

  7. Git branch -r 无法获取远程分支,ui可以看见分支但是git 命令无法查看解决方案

    zhc@hongchangfirst$ git checkout -b hongchangfirst origin/hongchangfirst 出现: fatal: Cannot update pa ...

  8. uwsgi+django 配置

    uwsgi+django 创建新的虚拟环境,且解决crm的环境依赖 在虚拟环境下安装uwsgi pip3 install uwsgi 学习uwsgi命令,如何启动python应用 启动python w ...

  9. Spark学习之路 (二十二)SparkStreaming的官方文档

    官网地址:http://spark.apache.org/docs/latest/streaming-programming-guide.html 一.简介 1.1 概述 Spark Streamin ...

  10. DataGuard之Apply Services(redo应用和SQL应用)

    应用服务 Apply Services 根据oracle官方文档整理 http://docs.oracle.com/cd/E11882_01/server.112/e25608/log_apply.h ...