欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-03-26 17:57:42
当我们在实际应用中需要提供撤销机制,当一个对象可能需要再后续操作中恢复其内部状态时,就需要使用备忘录模式。其本质就是对象的序列化和反序列化的过程,支持回滚操作。 作用 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以将该对象恢复到原先的状态。 类视图 实现 ......

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

作用

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

类视图

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

实现

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));

}

应用场景

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