您的位置:首页 > 其它

设计模式 - 备忘录模式

2015-02-04 17:32 225 查看
备忘录模式,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将该对象恢复到原先保存的状态。



Originator,负责创建一个Memento对象,用来记录它的当前内部状态,并可使用该Memento对象来恢复它的内部状态。Originator可根据需要,来决定Memento对象存储它的哪些状态。

Memento,备忘录类,负责存储Originator对象的内部状态,且防止Originator类以外的其他类的对象来访问Memento。Memento有两种接口,一种叫"宽接口",可使用该接口来返回保存的所有状态数据;一种叫"窄接口",并不能访问到备忘录内部保存的状态数据。

Caretaker,管理者类,负责保存Memento对象,但不能访问Memento内部保存的状态数据。Caretaker只能看到Memento的"窄接口"。

基本实现代码如下:

//备忘录类,保存Originator中的状态数据
class Memento
{
//Originator为友元类,只有Originator才能访问Memento中保存的数据
friend class Originator;

public:
Memento(string name, string sex, int age)
: m_strName(name), m_strSex(sex), m_nAge(age) {}

~Memento() {}

private:
string		m_strName;
string		m_strSex;
int			m_nAge;
};

//需要被保存状态的类
class Originator
{
public:
Originator(string name, string sex, int age)
: m_strName(name), m_strSex(sex), m_nAge(age) {}

~Originator() {}

//创建一个备忘录,保存数据
Memento *CreateMemento()
{
return  ( new Memento(m_strName, m_strSex, m_nAge) );
}

void ChangeState(string name, string sex, int age)
{
m_strName = name;
m_strSex = sex;
m_nAge = age;
}

//恢复上次保存的状态
void RecoverState(Memento *pMemento)
{
m_strName = pMemento->m_strName;
m_strSex = pMemento->m_strSex;
m_nAge = pMemento->m_nAge;
}

void PrintState()
{
printf("name:%s \t sex:%s \t age:%d \n", m_strName.c_str(), m_strSex.c_str(), m_nAge);
}

private:
string		m_strName;
string		m_strSex;
int			m_nAge;
};

//管理者,负责存储Memento对象
class Caretaker
{
public:
void SaveMemento(Memento *pMem) { m_pMem = pMem; }
Memento *GetMemento() { return m_pMem; }

private:
Memento *m_pMem;
};

//使用时的代码
int main()
{
Caretaker *pTaker = new Caretaker();

Originator *pOrigin = new Originator("zhou", "male", 23);
pOrigin->PrintState();

//创建备忘录,保存状态
Memento *pMem = pOrigin->CreateMemento();
pTaker->SaveMemento(pMem);

//改变状态
pOrigin->ChangeState("wang", "female", 30);
pOrigin->PrintState();

//恢复状态
pOrigin->RecoverState( pTaker->GetMemento() );
pOrigin->PrintState();
}
备忘录模式,把保存状态数据的细节封装在Memento中,客户端处并不知道要保存哪些数据,若以后要修改保存数据的细节,只要修改对应的Memento即可,不会影响到客户端的逻辑。

备忘录模式的使用场合:

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

备忘录模式的好处:

当对象的状态改变时,有可能这个状态无效,这时候就可以使用暂存起来的备忘录信息,把对象的状态复原。

备忘录模式在命令模式中的使用:

在系统中使用命令模式时,需要实现命令的撤销功能,此时,命令模式就可以使用备忘录模式来存储可撤销操作的状态。使用备忘录模式还可以把复杂对象的内部信息,对其他的对象屏蔽起来。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: