设计模式---状态变化模式之备忘录模式(Memento)

Posted ssyfj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式---状态变化模式之备忘录模式(Memento)相关的知识,希望对你有一定的参考价值。

一:概念

用于保存对象的内部状态,并在需要的时候(undo/rollback)回复对象以前的状态

二:应用场景

如果一个对象需要保存状态并可通过undo或rollback等操作恢复到以前的状态时,可以使用Memento模式。 

1)一个类需要保存它的对象的状态(相当于Originator角色); 
2)设计一个类,该类只是用来保存上述对象的状态(相当于Memento角色); 
3)需要的时候,Caretaker角色要求Originator返回一个Memento并加以保存; 
4)undo或rollback操作时,通过Caretacker保存的Memento恢复Originator对象的状态。

三:动机

在软件构建过程中,某些对象的状态在转换过程中,可能由于某种需求,要求程序能够回溯到对象之前处于某个点时的状态。如果使用一些公有接口来让其它对象得到对象的状态,便会暴露对象的实现细节。
如何实现对象状态的良好保存与恢复?但同时又不会因此而破坏对象本身的封装性。

四:模式定义

不破坏封装性(Originator)的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原想保存的状态。

                                                                    ——《设计模式》GoF

五:代码讲解

(一)需要保存状态的对象

class Originator
{
    string state;
    //....多个内部状态
public:
    Originator() {}
    Memento createMomento() {
        Memento m(state);  //在某个点时对状态(有可能需要编码序列化等操作)进行快照保存
        return m;
    }
    void setMomento(const Memento & m) {
        state = m.getState();  
    }
};

补充:

函数的局部对象在当前函数被调用的时候创建,存储在栈区,在函数结束以后就会被释放,如果存在返回值,那么当前对象也会被释放,只不过在被释放前
做了一次拷贝,拷贝到接受该返回值的另外一个对象上面,所以函数的入参和返回值其实都进行的是拷贝操作,新的对象被赋值,旧的的对象被回收

(二)外部保存对象状态的类

class Memento
{
    string state;  //保存方式多样,序列化,内存流等方式
    //..和上面状态对应,存储其中有效的状态(不一定是一模一样)
public:
    Memento(const string & s) : state(s) {}
    string getState() const { return state; }
    void setState(const string & s) { state = s; }
};

(三)使用

int main()
{
    Originator orginator;  //原发器
    
    //捕获对象状态,存储到备忘录
    Memento mem = orginator.createMomento();
    
    //... 改变orginator状态
    
    //从备忘录中恢复
    orginator.setMomento(memento);

}

六:类图(结构)

技术分享图片

七:要点总结

(一)备忘录(Memento)存储原发器(Originator)对象的内部状态,在需要时恢复原发器的状态。

(二)Memento模式的核心是信息隐藏,即Originator需要向外接隐藏信息,保持其封装性。但同时又需要将其状态保持到外界(Memento)

(三)由于现代语言运行时(如C#、java等)都具有相当的对象序列化支持,因此往往采用效率较高、又较容易正确实现的序列化方案来实现Memento模式。

 

以上是关于设计模式---状态变化模式之备忘录模式(Memento)的主要内容,如果未能解决你的问题,请参考以下文章

23种设计模式(十六)——备忘录模式状态变化

设计模式——17.备忘录模式

设计模式之状态模式与备忘录模式详解和应用

设计模式——16.状态模式

GoF 23 种设计模式之状态模式和备忘录模式

设计模式之备忘录模式