乐趣区

备忘录模式

简介

备忘录模式,不需要违反封装,捕获这个对象的状态,并且在外部保存对象的内部状态,以使对象可以恢复到之前的状态。

UML 类图

示例

word 编辑器提供了 undo 功能,在这里我们可以简单模拟一下此功能的实现,只显示最近的一个单词。
备忘录相关类,memento.h

#ifndef MEMENTO_H
#define MEMENTO_H
#include <string>
#include <vector>
#include <iostream>

using namespace std;
#define SAFE_DELETE(p) if(p){delete (p); (p) = NULL;}
class CWordMemento
{
public:
    CWordMemento(const string& strContent){m_strContent = strContent;}
    void SetContent(const string& strContent){m_strContent = strContent;}
    string GetContent(){ return m_strContent;}
private:
    string m_strContent;
};

class CEditOriginator
{
public:
    void SetMemento(CWordMemento* pMemento)
    {m_strContent = pMemento->GetContent();
    }
    void SetContent(const string& strContent)
    {
        m_strContent = strContent;
        cout<<"SetContent"<<strContent <<endl;
    }
    string GetContent()
    {return m_strContent;}
    CWordMemento* CreateMemento()
    {return new CWordMemento(m_strContent);
    }
private:
    string m_strContent;
};

class CWordCareTaker
{
public:
    CWordCareTaker(CEditOriginator* pOriginator){m_pOriginator = pOriginator;}
    void Save()
    {m_mementoContainer.push_back(m_pOriginator->CreateMemento());
    }
    void undo()
    {CWordMemento* pMemento = m_mementoContainer.back();
        m_pOriginator->SetMemento(pMemento);
        SAFE_DELETE(pMemento);
    }
private:
    vector<CWordMemento*> m_mementoContainer;
    CEditOriginator* m_pOriginator;
};

#endif

调用者,main.cpp

#include "memento.h"

int main(int argc, char* argv[])
{
    CEditOriginator* pOriginator = new CEditOriginator;
    CWordCareTaker* pCareTaker= new CWordCareTaker(pOriginator);

    pOriginator->SetContent("First");
    pCareTaker->Save();

    pOriginator->SetContent("Second");
    pCareTaker->Save();

    pOriginator->SetContent("Third");
    pCareTaker->undo();

    cout<<"Current content:"<<pOriginator->GetContent()<<endl;
    SAFE_DELETE(pCareTaker);
    SAFE_DELETE(pOriginator);
    return 0;
}

输出如下:

SetContent First
SetContent Second
SetContent Third
Current content: Second
退出移动版