您的位置:首页 > 编程语言 > C语言/C++

我所理解的设计模式(C++实现)——备忘录模式(Memento Pattern)

2013-08-04 21:35 686 查看

概述:

我们玩单机游戏的时候总会遇到老婆大人的各位事情,一会去买瓶醋了,一会去打个酱油了,会耽误我们玩游戏的进程,但是此时我们能有“保存游戏”这个宝贝,我们的主基地不会在我们打酱油的时候被对手拆掉。

这“保存游戏”的功能其实就是备忘录模式的很好应用,她是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以就该对象恢复到原先保存的状态。这个其实也是我们的redo,undo所采用的模式。

类图和实例:



简单的模式实例,来源于
网上

#include <iostream>
using namespace std;
class NumberMemento
{
friend class NumberOriginator;/*Friend Class for wide interface*/
public:
NumberMemento(){}
virtual ~NumberMemento(){}
/*narrow interface for state*/
virtual int GetNumberState()
{
return this->numberstate;
}

virtual void SetNumberState(int _newnumber)
{
this->numberstate=_newnumber;
return;
}

private:/*private is for encapsulation*/
int numberstate; /*wide interface for state*/

};

class MementoManager
{
public:
MementoManager(){}
virtual ~MementoManager(){}
/*interface to provide memento*/
virtual void SaveMemento(NumberMemento *_nummemento)
{
this->nummemento=_nummemento;
return;
}
virtual NumberMemento *GetMemento()
{
if(nummemento!=NULL)
return this->nummemento;
else
{
cout<<"No Memento Existed in MementoManager......Please create a memento for MementoManager first!"<<endl;
return NULL;
}
}

private:
NumberMemento *nummemento;// be managed memento,can be a list mementos
};

class NumberOriginator
{
public:
NumberOriginator(int _numstate,MementoManager *_manager)
{
this->NumberState=_numstate;
this->mementomanager=_manager;/*Conncetion with manager*/
}
virtual ~NumberOriginator(){}

virtual int getNumberState()
{
return this->NumberState;
}
virtual void SetNumberState(int _numstate)
{
this->StoreToMemento();
this->NumberState=_numstate;
return;
}
virtual void RestoreNumberState()/*Undo Operation*/
{
int lastState=(this->mementomanager->GetMemento())->numberstate;/*tell manager that I need memento state*/
(this->mementomanager->GetMemento())->numberstate=this->NumberState;
this->NumberState=lastState;
return;
}
protected:
virtual void StoreToMemento()
{
(this->mementomanager->GetMemento())->numberstate=this->NumberState;/*Use Wide Interface to memento */
return;
}
private:/*Important: 状态的封装性不能被破环*/
int NumberState;/*Number State*/
MementoManager *mementomanager;
};

int main (int argc, char *argv[])
{
/*New A memento and a Manager,and give the memento to manager*/
NumberMemento *memento=new NumberMemento();
MementoManager *caretaker=new MementoManager();
caretaker->SaveMemento(memento);
/*There is a number originator,it ask manager for memento*/
NumberOriginator *num=new NumberOriginator(11,caretaker);
cout<<"\nNumber Original State: "<<num->getNumberState()<<endl;
num->SetNumberState(22);
cout<<"\nNow Number State set tobe: "<<num->getNumberState()<<endl;
num->RestoreNumberState();/*Now Undo it*/
cout<<"\nNow Restore it(with Memento): "<<num->getNumberState()<<endl;
return(0);
}


适用性:

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

前提与说明:

备忘录模式使用的前提:

1) 必须保存一个对象在某一个时刻的(部分)状态, 这样以后需要时它才能恢复到先前的状态。

2) 如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。

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

关于第2点,我们可以让Memento声明Originator为她的私有友元类,这样Originator就可以访问Memento的所有函数。

LCL_data原创于CSDN.NET【http://blog.csdn.net/lcl_data/article/details/9745019】

其他设计模式文章请参考:我所理解的设计模式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐