C++设计模式——备忘录模式

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

 

 

 

Originator(发起人):负责创建一个Memento,用以记录当前时刻它自身的内部状态,并可以使用备忘录恢复内部状态。Originator可以根据需要决定Memento存储Originator的哪些内部状态(发起者可能有很多内部状态,可以决定哪些由备忘录备份)。
Memento(备忘录):负责存储Originator对象的内部状态,并可以防止Originator以外的其他对象访问备忘录Memento。备忘录有两个接口,Caretaker只能看到备忘录的窄接口,他只能将备忘录传递给其他对象。Originator能够看到一个宽接口,允许它访问先前状态所需的所有数据。
Caretaker(管理者):负责存储包备忘录Memento,不能对备忘录的内容进行操作或检查,只能够将备忘录传递给其它对象.

#include<iostream>
#include<string>
using namespace std;

//Memento类,备忘录,此处为角色状态存储箱
class RoleStateMemento
{
private:
    int m_vit; // 生命力
    int m_atk; // 攻击力
    int m_def; // 防御力
public:
    RoleStateMemento(int vit, int atk, int def) :m_vit(vit), m_atk(atk), m_def(def) {} // 把状态存入 备忘录中

    void setVitality(int vit) { m_vit = vit; }
    int getVitality() { return m_vit; }

    void setAttack(int atk) { m_atk = atk; }
    int getAttack() { return m_atk; }

    void setDefense(int def) { m_def = def; }
    int getDefense() { return m_def; }
};

// Originator,发起人,此处为游戏角色
class GameRole
{
private:
    int m_vit; // 生命力
    int m_atk; // 攻击力
    int m_def; // 防御力

public:
    RoleStateMemento* SaveState()
    {// 保存角色状态
        return (new RoleStateMemento(m_vit, m_atk, m_def));
    }
    void RecoveryState(RoleStateMemento* memento) // 恢复角色状态
    {
        m_vit = memento->getVitality();
        m_atk = memento->getAttack();
        m_def = memento->getDefense();
    }

    // 获得初始状态
    void GetInitState()
    {
        m_atk = m_def = m_vit = 100;
    }
    void Fight()
    {
        m_atk = m_def = m_vit = 0;
    }
    void StateDisplay()
    {
        cout << "角色当前状态:" << endl;
        cout << "体力:" << m_vit << " "
            << "攻击力:" << m_atk << " "
            << "防御力:" << m_def << endl;
    }
};
//Caretaker,管理者,此处为游戏角色管理类
class RoleStateCaretaker
{
private:
    RoleStateMemento* m_memento;
public:
    ~RoleStateCaretaker()
    {
        delete m_memento;
    }
    void setMemento(RoleStateMemento* memento)
    {
        m_memento = memento;
    }
    RoleStateMemento* getMemento()
    {
        return m_memento;
    }

};
int main()
{
    //大战Boss前
    GameRole* lixiaoyao = new GameRole;
    lixiaoyao->GetInitState();
    lixiaoyao->StateDisplay();

    //保存进度
    RoleStateCaretaker* stateAdmin = new RoleStateCaretaker;
    stateAdmin->setMemento(lixiaoyao->SaveState());

    //大战Boss时,损耗严重
    lixiaoyao->Fight();
    lixiaoyao->StateDisplay();

    //恢复之前状态               
    lixiaoyao->RecoveryState(stateAdmin->getMemento());
    lixiaoyao->StateDisplay();

    delete lixiaoyao;
    delete stateAdmin;

    system("pause");
    return 0;
}

 

 

要把保存的细节给封装再Memento中 哪一天要更改保存的细节也不影响客户端

应用场景

Memento模式比较适用于功能比较复杂的。但是需要维护或者记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分,Originator可以根据保存的Memento信息还原到某个状态

比如某个系统中使用命令模式,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销操作的状态.... 使用备忘录可以把复杂的对象内部信息对其他的对象屏蔽起来

 

我感觉最大的作用还是在于当角色状态改变的时候 有可能这个状态无效,这个时候就可以暂时存储起来的备忘录将状态复原

参考——大话设计模式

参考——大话设计模式 —— 第十八章《备忘录模式》C++ 代码实现_TAOTAO-CSDN博客

posted @ 2022-02-21 20:10  冰糖葫芦很乖  阅读(244)  评论(0编辑  收藏  举报