//---------------------------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. docker基础:dockerfile的介绍

    Dockerfile 是一个文本格式的配置文件,用户可以使用 Dockerfile 快速创建自定义的镜像.我们会先介绍 Dockerfile 的基本结构及其支持的众多指令,并具体讲解通过执行指令来编写 ...

  2. centos7 修改中文字符集

    CentOS 7字符集的问题与6有点区别,会出现下面问题,查看是中文,vi进入就变成乱码了 生产中修改配置文件   [root@ce1d2002a999 ~]# cat /etc/locale.con ...

  3. Web Services 根据wsdl生成代理类

    生成代理类步骤: 一:找到Visual Studio 的工具文件夹 二:用管理员方式打开本机工具命令提示 三:输入要执行的脚本 wsdl /language:C# /n:xxxx.HermesMobi ...

  4. Bitlocker驱动器加密使用

      前言 Bitlocker驱动器加密可以将磁盘加密,确保数据的安全.如果被加密保护的磁盘是Windows Server 2012操作系统磁盘,即使他被拿到另外一台计算机启动,除非已解锁,否则无法启动 ...

  5. Win7命令终端基础配色指南

    微软对控制台字体的元数据有严格的限制,https://support.microsoft.com/zh-cn/help/247815/necessary-criteria-for-fonts-to-b ...

  6. mysql数据库管理工具(navicat for mysql) 10.1.7 绿色中文版

    Navicat for MySQL:Navicat for MySQL 是一套专为 MySQL 设计的高性能数据库管理及开发工具.它可以用于任何版本 3.21 或以上的 MySQL 数据库服务器,并支 ...

  7. 小渣渣的json和jsonp和ajax的实质和区别

    json和jsonp和ajax的实质和区别ajax的两个问题 1.ajax以何种格式来交换数据 2.跨域的需求如何解决 数据跨域用自定义字符串或者用XML来描述 跨域可以用服务器代理来解决jsonp来 ...

  8. 安装和配置Apache服务器(下)

    Apache的配置文档:http://httpd.apache.org/docs/current/. 1.监听端口: 默认的端口号为80端口,如果端口号冲突改为8080端口. 注:每改一次httpd. ...

  9. 转,敏感词过滤,PHP实现的Trie树

    原文地址:http://blog.11034.org/2012-07/trie_in_php.html 项目需求,要做敏感词过滤,对于敏感词本身就是一个CRUD的模块很简单,比较麻烦的就是对各种输入的 ...

  10. MYSQL一次千万级连表查询优化(一)

    摘自网上学习之用 https://blog.csdn.net/Tim_phper/article/details/78344444 概述: 交代一下背景,这算是一次项目经验吧,属于公司一个已上线平台的 ...