Memento模式
一、意图
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
二、适用性
必须保存一个对象在某一个时刻的(部分)状态, 这样以后需要时它才能恢复到先前的状态。
如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。
三、结构
Originator(发起人):负责创建一个备忘录Memento,用以记录当前时刻自身的内部状态,并可使用备忘录恢复内部状态。Originator可以根据需要决定Memento存储自己的哪些内部状态。
Memento(备忘录):负责存储Originator对象的内部状态,并可以防止Originator以外的其他对象访问备忘录。备忘录有两个接口:Caretaker只能看到备忘录的窄接口,他只能将备忘录传递给其他对象。Originator却可看到备忘录的宽接口,允许它访问返回到先前状态所需要的所有数据。
Caretaker(管理者):负责备忘录Memento,不能对Memento的内容进行访问或者操作。
四、代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <math.h>
#include <qxmlstream.h>
#include <QDebug>
#include <windows.h>
#include <unistd.h>
#include <QApplication>
class CMemento
{
public:
CMemento()
{
m_value = 0;
}
void SetState(int val)
{
m_value = val;
}
int GetState()
{
return m_value;
}
private:
int m_value;
};
class CCaretaker
{
public:
CMemento GetMemento()
{
qDebug("GetMemento %ld, add %ld, this add %ld",
m_saveMemento.GetState(), &m_saveMemento, this);
return this->m_saveMemento;
}
void SetMemento(CMemento mem)
{
m_saveMemento = mem;
qDebug("SetMemento %ld, add %ld, this add %ld",
m_saveMemento.GetState(), &m_saveMemento, this);
}
private:
CMemento m_saveMemento;
};
class COriginator
{
public:
COriginator(int val)
{
m_value = val;
// m_pCaretaker = new CCaretaker();
}
int GetState()
{
return m_value;
}
CMemento SaveState()
{
CMemento memento;
memento.SetState(m_value);
return memento;
}
void RestoreState(CMemento memento)
{
this->m_value = memento.GetState();
}
void StateChange()
{
m_value = rand() % 100;
}
// CCaretaker GetCaretaker()
// {
// return m_pCaretaker;
// }
private:
int m_value;
// CCaretaker m_pCaretaker;
};
int main(int argc, char** argv)
{
QApplication app(argc, argv);
COriginator original(100);
CCaretaker m_caretaker;
qDebug("1 Current state = %ld", original.GetState());
m_caretaker.SetMemento(original.SaveState());
original.StateChange();
qDebug("2 Current state = %ld", original.GetState());
original.RestoreState(m_caretaker.GetMemento());
qDebug("3 Current state = %ld", original.GetState());
return app.exec();
}