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

类图和实例:

简单的模式实例:
#include <iostream>
#include <string>
using namespace std;
class Memento {
private:
    string state; public:
    Memento()
    {
        state = "";
    }
    Memento(string state){
        this->state = state;
    }
    string getState() {
        return state;
    }
    void setState(string state) {
        this->state = state;
    }
}; class Originator {
private :
    string state; public:
    Originator()
    {
        state = "";
    }     string getState() {
        return state;
    }
    void setState(string state) {
        this->state = state;
    }
    Memento createMemento(){
        return Memento(this->state);
    }
    void restoreMemento(Memento memento){
        this->setState(memento.getState());
    }
}; class Caretaker {
private :
    Memento memento;
public :
    Memento getMemento(){
        return memento;
    }
    void setMemento(Memento memento){
        this->memento = memento;
    }
};
int main (int argc, char *argv[])   
{
    Originator originator;
    originator.setState("状态1");
    cout<<"初始状态:"<<originator.getState()<<endl;
    Caretaker caretaker;
    caretaker.setMemento(originator.createMemento());
    originator.setState("状态2");
    cout<<"改变后状态:"<<originator.getState()<<endl;
    originator.restoreMemento(caretaker.getMemento());
    cout<<"恢复后状态:"<<originator.getState()<<endl;
}

UML类图

Memento:备忘录存储原发器对象的内部状态。原发器根据需要决定备忘录存储原发器的哪些内部状态;防止原发器以外的其他对象访问备忘录。备忘录实际上有两个接口,管理者只能看到备忘录的窄接口————它只能将备忘录传递给其他对象。相反,原发器能够看到一个宽接口,允许它访问返回到先前状态所需的所有数据。理想的情况是只允许生成备忘录的那个原发器访问本备忘录的内部状态;
Originator:原发器创建一个备忘录,用以记录当前时刻它的内部状态;我们使用备忘录恢复内部状态;
Caretaker:负责保存好备忘录;但是,不能对备忘录的内容进行操作或检查。

备忘录模式是按照以下方式进行协作的:
管理器向原发器请求一个备忘录,保留一段时间后,将其送回给原发器;而有的时候管理者不会将备忘录返回给原发器,因为原发器可能根本不需要退到先前的状态。备忘录是被动的,只有创建备忘录的原发器会对它的状态进行赋值和检索,如下面的时序图:

#include <iostream>
using namespace std; struct State
{
wchar_t wcsState[];
}; class Memento
{
public:
Memento(State *pState) : m_pState(pState){} State *GetState() { return m_pState; } private:
friend class Originator; State *m_pState;
}; class Originator
{
public:
Originator() : m_pState(NULL) {}
~Originator()
{
// Delete the storage of the state
if (m_pState)
{
delete m_pState;
m_pState = NULL;
}
} void SetMemento(Memento *pMemento);
Memento *CreateMemento(); void SetValue(wchar_t *value)
{
memset(wcsValue, , * sizeof(wchar_t));
wcscpy_s(wcsValue, , value);
} void PrintState() { wcout<<wcsValue<<endl; } private:
State *m_pState; // To store the object's state wchar_t wcsValue[]; // This is the object's real data
}; Memento *Originator::CreateMemento()
{
m_pState = new State;
if (m_pState == NULL)
{
return NULL;
} Memento *pMemento = new Memento(m_pState); wcscpy_s(m_pState->wcsState, , wcsValue); // Backup the value
return pMemento;
} void Originator::SetMemento(Memento *pMemento)
{
m_pState = pMemento->GetState(); // Recovery the data
memset(wcsValue, , * sizeof(wchar_t));
wcscpy_s(wcsValue, , m_pState->wcsState);
} // Manager the Memento
class Caretaker
{
public:
Memento *GetMemento() { return m_pMemento; }
void SetMemnto(Memento *pMemento)
{
// Free the previous Memento
if (m_pMemento)
{
delete m_pMemento;
m_pMemento = NULL;
} // Set the new Memento
m_pMemento = pMemento;
} private:
Memento *m_pMemento;
}; int main()
{
Originator *pOriginator = new Originator();
pOriginator->SetValue(L"On");
pOriginator->PrintState(); // Now I backup the state
Caretaker *pCaretaker = new Caretaker();
pCaretaker->SetMemnto(pOriginator->CreateMemento()); // Set the new state
pOriginator->SetValue(L"Off");
pOriginator->PrintState(); // Recovery to the old state
pOriginator->SetMemento(pCaretaker->GetMemento());
pOriginator->PrintState(); if (pCaretaker)
{
delete pCaretaker;
} if (pOriginator)
{
delete pOriginator;
} return ;
}

适用性:

适用于功能比较复杂的,但需要记录或维护属性历史的类;或者需要保存的属性只是众多属性中的一小部分时Originator可以根据保存的Memo还原到前一状态。

优缺点:

优点:

1)当发起人角色的状态有改变时,有可能是个错误的改变,我们使用备忘录模式就可以把这个错误改变还原。

2)备份的状态是保存在发起人角色之外的,这样,发起人角色就不需要对各个备份的状态进行管理。

缺点:

1)如果备份的对象存在大量的信息或者创建、恢复操作非常频繁,则可能造成很大的性能开销。

 
 

[设计模式] 18 备忘录模式Memento Pattern的更多相关文章

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

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

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

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

  3. 备忘录模式-Memento Pattern(Java实现)

    备忘录模式-Memento Pattern Memento备忘录设计模式是一个保存另外一个对象内部状态拷贝的对象,这样以后就可以将该对象恢复到以前保存的状态. 本文中的场景: 有一款游戏可以随时存档, ...

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

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

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

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

  6. 23.备忘录模式(Memento Pattern)

    using System; using System.Collections.Generic; namespace ConsoleApplication6 { /// <summary> ...

  7. 备忘录模式-Memento Pattern

    1.主要优点 备忘录模式的主要优点如下: (1)它提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原. (2) ...

  8. 设计模式 笔记 备忘录模式 Memento

    //---------------------------15/04/27---------------------------- //Memento 备忘录模式----对象行为型模式 /* 1:意图 ...

  9. 用最简单的例子理解备忘录模式(Memento Pattern)

    简单来说,备忘录模式就是支持回退操作.假设让一个Notepad支持回退操作,如何实现呢? 首先需要一个备忘录类. public class Memento { private string _msg; ...

随机推荐

  1. J2EE5(Servlet2.5)对EL表达式的支持

    JAVA EE5默认 支持EL表达式. 办法一:在每个jsp文件的最上方加入以下代码: <%@ page language="java" import="java. ...

  2. C++11智能指针

    今晚跟同学谈了一下智能指针,突然想要看一下C++11的智能指针的实现,因此下了这篇博文. 以下代码出自于VS2012 <memory> template<class _Ty> ...

  3. 基于Httpfs访问HDFS的C++实现

    Httpfs是hadoop2.x中hdfs项目的内置应用,基于tomcat和jesery,对外提供完备HDFS操作的RESTful接口,无需安装客户端,可方便实现数据交互,如从windows访问存储在 ...

  4. grep恢复误删除文件内容(转)

    在 Linux 上如果事先没有用别名(alias)修改默认的 rm 功能,rm 后文件就会丢失,幸运的是,在一般的删除文件操作中,Linux 并不会立即清空存储该文件的 block 内容,而只会释放该 ...

  5. web前端学习之HTML CSS/javascript之一

    前端编码之路之坎坷,web前端应该一直是个战场吧,各种浏览器的不兼容,各种小细节的修改,要往一个好的产品经理方向走,实在是难,昨天听了一位十年经验的产品经理讲座,最重要的恐怕就是协调资源的能力,而协调 ...

  6. js设计模式(5)---外观模式

    0.前言 早上好,今天天气不错,估计有35度吧,坐在空调室里相当惬意,那么酒足饭饱之后就应该干些正事了. 1. 为什么使用外观模式 外观模式提供了一个高层接口,封装一些复杂操作或繁琐行为,方便调用.门 ...

  7. js设计模式(4)---组合模式

    0.前言 今天是建党节,新疆那边又开始了闹腾.作为立志成为码农的我,现在已经从一个大愤青淡化为一个小愤青,对这些国家民生大事不在血气喷发,转而把经历发泄在技术问题上面,因而在扯一篇随笔吧,把无处发泄的 ...

  8. 身处IT的你对身边人都有哪些影响

    前不久,跟外甥一起吃饭:他明年就要中考了,我就想,这马上就到人生的关键路口了,看他自己对将来有什么想法没:就问了句:勇勇,你以后想学习哪些方面的东西或者想从事什么工作呢?他简单的说了句:我要跟你一样学 ...

  9. GitHub for Windows离线安装的方法

    这几天一直在尝试安装GitHub for windows ,安装程序是从https://windows.github.com/ 下载到的OneClick 部署程序,版本号为2.11.0.5.可能是因为 ...

  10. windows7 64bit下安装Oracle 11g R2

    Win7 bit64,安装的是64位的客户端.   1.PLSql连接数据库   (1)下载 instantclient-basic-win32-11.2.0.1.0.zip解压到Oracle要目当下 ...