备忘录模式

备忘录模式

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

  • Originator(发起人):负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态。Originator 可根据需要决定 Memento 存储 Originator 的哪些内部状态。

  • Memento(备忘录):负责存储 Originator 对象的内部状态,并可防止 Originator 以外的其他对象访问备忘录 Memento。备忘录有两个接口。

    • Caretaker 只能看到备忘录的窄接口,它只能将备忘录传递给其他对象
    • Originator 能够看到一个宽接口,允许它访问返回到先前状态所需的所有数据。
  • Caretaker(管理者):负责保存好备忘录
    ,不能对备忘录的内容进行操作或检查。
示例代码
//备忘录模式
//备忘录类
class Memento
{
public:
    Memento() = default;
    Memento(string state) :m_state(state){}
    string GetState(){ return m_state; }
private:
    string m_state;
};
//Originator(发起人):负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态。
class Originator
{
public:
    string GetState(){ return m_state; }
    void SetState(string state){ m_state = state; }
    Memento* CreateMemento(){ return new Memento(m_state); }
    void SetMemento(Memento memento){ m_state = memento.GetState(); }
private:
    string m_state;
};

//管理者类
class Caretaker
{
public:
    Memento GetMemento(){ return m_memento; }
    void SetMemento(Memento memento){ m_memento = memento; }
private:
    Memento m_memento;
};

测试程序:

int main()
{
    //原始数据
    Originator o;
    o.SetState("ON");
    cout << "备份前:"<<o.GetState() << endl;

    //备忘录
    Caretaker c;
    c.SetMemento(o.CreateMemento());
    o.SetState("OFF");
    cout << "备份后:" << o.GetState() << endl;

    //恢复备份数据
    o.SetMemento(c.GetMemento());
    cout << "恢复备份:" << o.GetState() << endl;

    system("pause");
    return 0;
}

运行结果:
这里写图片描述

备忘录模式用的场合
  • 比较适用于功能比较复杂的,但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分时,Originator 可以根据保存的 Memento 信息还原到前一状态。
  • 如果在某个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销操作的状态。
  • 使用备忘录模式可以把复杂的对象内部信息对其他对象屏蔽起来。
游戏进度备份代码
//游戏进度备忘
//角色状态存储
class RoleStateMemento
{
public:
    RoleStateMemento() = default;
    RoleStateMemento(int life, int atk) :m_life(life), m_atk(atk){}
    int GetLife(){ return m_life; }
    int GetAtk(){ return m_atk; }
private:
    int m_life;
    int m_atk;
};
//游戏角色
class GameRole
{
public:
    GameRole() = default;
    GameRole(int life, int atk) :m_life(life), m_atk(atk){}
    //保存角色
    RoleStateMemento SaveState(){ return RoleStateMemento(m_life, m_atk); }
    //恢复角色
    void RecoveryState(RoleStateMemento memento){ m_life = memento.GetLife(); m_atk = memento.GetAtk(); }
    void Set_Life(int life){ m_life = life; }
    void Set_Atk(int atk){ m_atk = atk; }
    void show(){ cout << "生命值:" << m_life  << "攻击力:" << m_atk << endl; }
private:
    int m_life;
    int m_atk;
};
//角色状态管理类
class RoleStateCaretaker
{
public:
    RoleStateMemento GetMemento(){ return m_mement; }
    void SetMement(RoleStateMemento &mement){ m_mement = mement; }
private:
    RoleStateMemento m_mement;
};

int main()
{
    //初始化角色
    GameRole zjy(100, 10);

    //保存进度
    RoleStateCaretaker State;
    State.SetMement(zjy.SaveState());

    //备忘以后继续游戏
    zjy.Set_Atk(20);
    zjy.Set_Life(95);
    zjy.show();

    //恢复之前的状态
    zjy.RecoveryState(State.GetMemento());
    cout << "恢复备忘后:";
    zjy.show();

    system("pause");
    return 0;
}

运行结果:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值