设计模式之备忘录模式(Memento )

vczh的日常 2018-04-12

当我们在实际应用中需要提供撤销机制,当一个对象可能需要再后续操作中恢复其内部状态时,就需要使用备忘录模式。其本质就是对象的序列化和反序列化的过程,支持回滚操作。

作用

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

类视图

实现

typedef struct sysstate; //假设的一个空结构,用来代表系统状态

//还原点
class Memento
{
public:
    Memento(sysstate &statein)
    {
        state = statein;
    }
    sysstate& getstate(){ return state}
private:
    sysstate state;
};

//运行系统
class system
{
public:
    void recovery(Memento* pMem)
    {
        if (pMem)
        {
            state = pMem->getstate();
        }        
    }
    Memento* backup()
    {
        return new Memento(state);
    }
private:
    sysstate state;
};

//还原控制器
class recoveryControl
{
public:
    ~recoveryControl()
    {
        map<long,Memento*>::iterator iter;  
        for ( iter = m_mementos.begin(); iter != m_mementos.end(); iter++)
        {
            delete iter.second;
        }
    }
    long addRecoveryPoint(Memento* pMem)
    {
        long t = clock();
        m_mementos.instert(pair<long,Memento*>(t, pMem));
        return t;
    }
    Memento* GetRecoveryPoint(long time)
    {
        map<long,Memento*>::iterator iter;  
  
        iter = m_mementos.find(time);  
  
        if(iter != m_mementos.end())  
            return iter->second;    
        return NULL;
    }
    void DelRecoveryPoint(long time)
    {
        Memento* pMem = GetRecoveryPoint(time);
        m_mementos.erase(time);       
        delete pMem;
    }
private:
    map<long,Memento*> m_mementos;
};

int main()
{
    system Sys;
    recoveryControl controler;
    //备份系统并存入备份管理器中
    long time1 = controler.addRecoveryPoint(Sys.backup());
    long time2 = controler.addRecoveryPoint(Sys.backup());

    //将系统恢复到time1状态
    Sys.recovery(controler.GetRecoveryPoint(time1));

    //将系统恢复到time2状态
    Sys.recovery(controler.GetRecoveryPoint(time2));

}

应用场景

支持回滚操作的 地方,如游戏存档、事务回滚、程序的撤销和恢复操作等。

相关推荐