• [大话设计模式C++版] 第18章 如果再回到从前 —— 备忘录模式


    源码可以在这里找到 大话设计模式C++版

    游戏存进度

    //GameRole.h 游戏角色类
    #pragma execution_character_set("utf-8")
    #include 
    
    class GameRole
    {
    private:
        int m_hp;  //生命力
        int m_atk;  //攻击力
        int m_def;  //防御力
    public:
        void stateDisplay() {
            qDebug() << QString("角色当前状态:");
            qDebug() << QString("体力:%1").arg(m_hp);
            qDebug() << QString("攻击力:%1").arg(m_atk);
            qDebug() << QString("防御力:%1").arg(m_def);
            qDebug() << "";
        }
        void getInitState() {
            m_hp = 100;
            m_atk = 100;
            m_def = 100;
        }
        void fight() {
            m_hp = 0;
            m_atk = 0;
            m_def = 0;
        }
        int getHp() const {
            return m_hp;
        }
        void setHp(int hp) {
            m_hp = hp;
        }
        int getAtk() const {
            return m_atk;
        }
        void setAtk(int atk) {
            m_atk = atk;
        }
        int getDef() const {
            return m_def;
        }
        void setDef(int def) {
            m_def = def;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    //main.cpp 客户端代码
    #include "GameRole.h"
    #include 
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        //大战Boss前
        shared_ptr<GameRole> lixiaoyao(new GameRole());
        lixiaoyao->getInitState();
        lixiaoyao->stateDisplay();
    
        //保存进度
        shared_ptr<GameRole> backup(new GameRole());
        backup->setHp(lixiaoyao->getHp());
        backup->setAtk(lixiaoyao->getAtk());
        backup->setDef(lixiaoyao->getDef());
    
        //大战Boss时,损耗严重
        lixiaoyao->fight();
        lixiaoyao->stateDisplay();
    
        //恢复之前状态
        lixiaoyao->setHp(backup->getHp());
        lixiaoyao->setAtk(backup->getAtk());
        lixiaoyao->setDef(backup->getDef());
    
        lixiaoyao->stateDisplay();
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    运行结果:

    "角色当前状态:"
    "体力:100"
    "攻击力:100"
    "防御力:100"
    
    "角色当前状态:"
    "体力:0"
    "攻击力:0"
    "防御力:0"
    
    "角色当前状态:"
    "体力:100"
    "攻击力:100"
    "防御力:100"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    备忘录模式基本代码

    在这里插入图片描述

    //Originator.h 发起人类
    #include 
    #include 
    #include 
    #include "Memento.h"
    
    using namespace std;
    
    class Originator
    {
    private:
        QString m_state;
    public:
        shared_ptr<Memento> CreateMemento() {
            return shared_ptr<Memento>(new Memento(m_state));
        }
        void setMemento(shared_ptr<Memento> memento) {
            m_state = memento->getState();
        }
        void show() {
            qDebug() << QString("State = %1").arg(m_state);
        }
        const QString &getState() const {
            return m_state;
        }
        void setState(const QString &state) {
            m_state = state;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    //Memento.h 备忘录类
    #include 
    
    class Memento
    {
    private:
        QString m_state;
    public:
        Memento(QString state) : m_state(state) {}
        QString getState() {
            return m_state;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    //Caretaker.h 管理者类
    #include "Memento.h"
    #include 
    
    using namespace std;
    
    class Caretaker
    {
    private:
        shared_ptr<Memento> m_memento;
    public:
        const shared_ptr<Memento> &getMemento() const {
            return m_memento;
        }
        void setMemento(const shared_ptr<Memento> &memento) {
            m_memento = memento;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    //main.cpp 客户端代码
    #include 
    #include "Originator.h"
    #include "Caretaker.h"
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        shared_ptr<Originator> o(new Originator());
        o->setState("On");
        o->show();
    
        shared_ptr<Caretaker> c(new Caretaker());
        c->setMemento(o->CreateMemento());
    
        o->setState("Off");
        o->show();
    
        o->setMemento(c->getMemento());
        o->show();
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    运行结果:

    "State = On"
    "State = Off"
    "State = On"
    
    • 1
    • 2
    • 3

    游戏进度备忘

    在这里插入图片描述

    //GameRole.h 游戏角色类增加的内容
    #include "RoleStateMemento.h"
    #include 
    
    using namespace std;
    
    class GameRole
    {
        //...
    public:
        //...
        shared_ptr<RoleStateMemento> saveState() {
            return shared_ptr<RoleStateMemento>(new RoleStateMemento(m_hp, m_atk, m_def));
        }
        void recoveryState(shared_ptr<RoleStateMemento> memento) {
            m_hp = memento->getHp();
            m_atk = memento->getAtk();
            m_def = memento->getDef();
        }
        //...
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    //RoleStateMemento.h 角色状态存储箱类
    class RoleStateMemento
    {
    private:
        int m_hp;  //生命力
        int m_atk;  //攻击力
        int m_def;  //防御力
    public:
        RoleStateMemento(int hp, int atk, int def) : m_hp(hp), m_atk(atk), m_def(def) {}
        int getHp() const {
            return m_hp;
        }
        void setHp(int hp) {
            m_hp = hp;
        }
        int getAtk() const {
        	return m_atk;
        }
        void setAtk(int atk) {
            m_atk = atk;
        }
        int getDef() const {
            return m_def;
        }
        void setDef(int def) {
            m_def = def;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    //RoleStateCaretaker.h 角色状态管理者
    #include 
    #include "RoleStateMemento.h"
    
    using namespace std;
    
    class RoleStateCaretaker
    {
    private:
        shared_ptr<RoleStateMemento> m_memento;
    public:
        const shared_ptr<RoleStateMemento> &getMemento() const {
            return m_memento;
        }
        void setMemento(const shared_ptr<RoleStateMemento> &memento) {
            m_memento = memento;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    //main.cpp 客户端代码
    #include "GameRole.h"
    #include 
    #include "RoleStateCaretaker.h"
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        //大战Boss前
        shared_ptr<GameRole> lixiaoyao(new GameRole());
        lixiaoyao->getInitState();
        lixiaoyao->stateDisplay();
    
        //保存进度
        shared_ptr<RoleStateCaretaker> stateAdmin(new RoleStateCaretaker());
        stateAdmin->setMemento(lixiaoyao->saveState());
    
        //大战Boss时,损耗严重
        lixiaoyao->fight();
        lixiaoyao->stateDisplay();
    
        //恢复之前状态
        lixiaoyao->recoveryState(stateAdmin->getMemento());
    
        lixiaoyao->stateDisplay();
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    运行结果:

    "角色当前状态:"
    "体力:100"
    "攻击力:100"
    "防御力:100"
    
    "角色当前状态:"
    "体力:0"
    "攻击力:0"
    "防御力:0"
    
    "角色当前状态:"
    "体力:100"
    "攻击力:100"
    "防御力:100"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    Memento备忘录模式 [李建忠C++笔记]

    "状态变化"模式

    • 在组件构建过程中,某些对象的状态的状态经常面临变化,如何对这些变化进行有效的管理?同时又维持高层模块的稳定?“状态变化”模式为这一问题提供了一种解决方案。
    • 典型模式
      • State
      • Memento

    动机(Motivation)

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

    模式定义

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

    //Memento.cpp
    class Memento
    {
    	string state;
    public:
    	Memento(const string& s) : state(s) {}
    	string getState() const { return state; }
    	void setState(const string& s) { state = s; }
    };
    
    class Originator
    {
    	string state;
    	//...
    public:
    	Originator() {}
    	Memento createMomento() {
    		Memento m(state);
    		return m;
    	}
    	void setMomento(const Memento& m) {
    		state = m.getState();
    	}
    };
    
    int main()
    {
    	Originator originator;
    	
    	//捕获对象状态,存储到备忘录
    	Memento mem = orginator.createMomento();
    	
    	//... 改变orginator状态
    	
    	//从备忘录中恢复
    	orginator.setMomento(mem);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    在这里插入图片描述

    要点总结

    • 备忘录(Memento)存储原发器(Originator)对象的内部状态在需要时恢复原发器状态。
    • Memento模式的核心是信息隐藏,即Originator需要向外界隐藏信息,保持其封装性。但同时又需要将状态保持到外界(Memento)。
    • 由于现代语言运行时(如C#、Java等)都具有相当的对象序列化支持,因此往往采用效率较高、有较容易正确实现的序列化方案来实现Memento模式。
  • 相关阅读:
    【云原生 | 从零开始学Kubernetes】二十七、配置管理中心Secret和rbac授权
    字符串4:反转字符串中的单词
    【CSPNet】《CSPNet:A New Backbone that can Enhance Learning Capability of CNN》
    特殊字符串转成树形结构
    JavaScript小技能:原型链的运作机制、Promise链
    【音视频】H264视频压缩格式
    OFD转PDF ~java实现
    小白学流程引擎-FLowable(三) —流程设计器Flowable UI
    Java 网络编程 —— 创建非阻塞的 HTTP 服务器
    推荐6个AI工具网站
  • 原文地址:https://blog.csdn.net/weixin_40743639/article/details/127417957