Memorandum model

Time:2020-8-18

brief introduction

In memo mode, the state of the object is captured without violating encapsulation, and the internal state of the object is saved externally so that the object can be restored to its previous state.

UML class diagram

Memorandum model

Examples

The word editor provides the Undo function. Here we can simply simulate the implementation of this function and only display the latest word.
Memo related class, 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

Callers, 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;
}

The output is as follows:

SetContent First
SetContent Second
SetContent Third
Current content: Second