zoukankan      html  css  js  c++  java
  • 我所理解的设计模式(C++实现)——备忘录模式(Memento Pattern)

    概述:

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

        这“保存游戏”的功能其实就是备忘录模式的很好应用,她是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以就该对象恢复到原先保存的状态。这个其实也是我们的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<<"
    Number Original State: "<<num->getNumberState()<<endl;  
    	num->SetNumberState(22);  
    	cout<<"
    Now Number State set tobe: "<<num->getNumberState()<<endl;  
    	num->RestoreNumberState();/*Now Undo it*/  
    	cout<<"
    Now 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】

    其他设计模式文章请参考:我所理解的设计模式

  • 相关阅读:
    开启linux服务器防火墙
    Linux系统编程11_管道和命名管道
    Lua语法
    Git学习
    Buildroot介绍
    Makefile基本介绍
    页、页表和块
    文件系统,根文件系统,MTD
    什么是ioctl
    bootargs的mtdparts解析
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3237061.html
Copyright © 2011-2022 走看看