• 备忘录模式 (c++实现)


    模式定义

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

    模式动机

    • 备忘录模式比较适用于功能比较复杂的,但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分时,LieKong可以根据stateManager保存的BaseState信息换遇到前一状态。

    UML类图

    备忘录模式

    设计介绍

    • LieKong

      游戏角色,拥有属性BaseState。一个可以回到过去的技能UnleashSkills

    • BaseState

      封装任务状态:三维坐标和血量两个状态

    • StateManager

      记录角色前一个状态

    源码实现

    • baseState.h
    #ifndef BASESTATE_H
    #define BASESTATE_H
    
    #include <QObject>
    
    class BaseState : public QObject
    {
        Q_OBJECT
    public:
        struct POSITION
        {
            int x;
            int y;
            int z;
        };
        explicit BaseState(QObject *parent = nullptr);
        explicit BaseState(POSITION pos, int xl, QObject *parent = nullptr);
        BaseState(const BaseState& state);
        BaseState& operator=(const BaseState& state);
    
        void SetPositon(POSITION pos);
        void SetXL(int xl);
        void PrintState();
    signals:
    
    public slots:
    
    private:
        POSITION m_Position;//位置
        int     m_Xl;//血量
    };
    
    #endif // BASESTATE_H
    
    
    • baseState.cpp
    #include <QDebug>
    #include "basestate.h"
    
    BaseState::BaseState(QObject *parent)
    {
    
    }
    
    BaseState::BaseState(POSITION pos, int xl, QObject *parent)
    : QObject(parent), m_Position(pos), m_Xl(xl)
    {
    
    }
    
    BaseState::BaseState(const BaseState &state)
    {
         if(this != &state)
        {
            this->m_Xl = state.m_Xl;
            this->m_Position.x = state.m_Position.x;
            this->m_Position.y = state.m_Position.y;
            this->m_Position.z = state.m_Position.z;
        }
    }
    
    BaseState &BaseState::operator=(const BaseState &state)
    {
        if(this != &state)
        {
            this->m_Xl = state.m_Xl;
            this->m_Position.x = state.m_Position.x;
            this->m_Position.y = state.m_Position.y;
            this->m_Position.z = state.m_Position.z;
        }
        return *this;
    }
    
    void BaseState::SetPositon(POSITION pos)
    {
        m_Position.x = pos.x;
        m_Position.y = pos.y;
        m_Position.z = pos.z;
    }
    
    void BaseState::SetXL(int xl)
    {
        m_Xl = xl;
    }
    
    void BaseState::PrintState()
    {
            qDebug() << QString("现在的坐标是:x = %1, y = %2, z = %3;").arg(m_Position.x).arg(m_Position.y).arg(m_Position.z);
            qDebug() << QString("现在的血量是:%1").arg(m_Xl);
            qDebug() << endl;
    }
    
    
    • liekong.h
    #ifndef LIEKONG_H
    #define LIEKONG_H
    
    #include <QObject>
    #include <functional>
    #include "basestate.h"
    
    using skill1 = std::function<bool (int)>;
    using skill2 = std::function<void(void)>;
    using skill3 = std::function<void(void)>;
    
    class Liekong : public QObject
    {
        Q_OBJECT
    public:
        explicit Liekong(QObject *parent = nullptr);
        BaseState State();
        void SetState(BaseState state);
    
        void UnleashSkills(const skill1& skill);//释放时光倒回技能
        void ChangeState();//改变状态
    private:
        BaseState CreateState();
    
    signals:
    
    public slots:
    private:
        BaseState m_State;
    };
    
    #endif // LIEKONG_H
    
    
    • liekong.cpp
    #include <QDebug>
    #include "liekong.h"
    
    Liekong::Liekong(QObject *parent) : QObject(parent)
    {
        CreateState();
    }
    
    BaseState Liekong::State()
    {
        m_State.PrintState();
        return m_State;
    }
    
    void Liekong::SetState(BaseState state)
    {
        m_State= state;
    }
    
    BaseState Liekong::CreateState()
    {
        BaseState::POSITION pos;
        pos.x = 20;
        pos.y = 50;
        pos.z = 67;
        m_State = BaseState(pos, 100);
        return m_State;
    }
    
    void Liekong::UnleashSkills(const skill1& skill)
    {
        int a = 0;
        skill(a);
    }
    
    void Liekong::ChangeState()
    {
        BaseState::POSITION pos;
        pos.x = 10;
        pos.y = 10;
        pos.z = 10;
        m_State.SetPositon(pos);
        m_State.SetXL(10);
    }
    
    
    • statemanager.h
    #ifndef STATEMANAGER_H
    #define STATEMANAGER_H
    
    #include <QObject>
    #include "basestate.h"
    
    class StateManager : public QObject
    {
        Q_OBJECT
    public:
        explicit StateManager(QObject *parent = nullptr);
    
        void SetState(const BaseState& state);
        BaseState State();
    
    signals:
    public slots:
    
    private:
        BaseState m_State;
    };
    
    #endif // STATEMANAGER_H
    
    
    • satemanager.cpp
    #include "statemanager.h"
    
    StateManager::StateManager(QObject *parent) : QObject(parent)
    {
    
    }
    
    void StateManager::SetState(const BaseState& state)
    {
        m_State = state;
    }
    
    BaseState StateManager::State()
    {
        return m_State;
    }
    
    
    • main.cpp
    /************************************
        * @brief	:  需要三个类,我们以 守望先锋 里的裂空的一个回到去过去的技能为背景写一个实现
        * @author	:   wzx
        * @date	:   2020-04-30
        * @project	:  Memento
    *************************************/
    #include <QCoreApplication>
    #include <QDebug>
    #include "liekong.h"
    #include "statemanager.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        
        Liekong lk;
        qDebug() << "初始状态:";
        BaseState state = lk.State();
        
        StateManager manage;
        manage.SetState(state);
        
        lk.ChangeState();
        qDebug() << "更新后状态:";
        lk.State();
        
        BaseState state1 = manage.State();
        
        lk.UnleashSkills([&lk, state1](int a){
            lk.SetState(state1);
            qDebug() << "param = " << a;
            return true;
        });
        qDebug() << "还原后状态:";
        lk.State();
        
        return a.exec();
    }
    
    
    • 运行结果

    初始状态:

    "现在的坐标是:x = 20, y = 50, z = 67;"

    "现在的血量是:100"

    更新后状态:

    "现在的坐标是:x = 10, y = 10, z = 10;"

    "现在的血量是:10"

    还原后状态:

    "现在的坐标是:x = 20, y = 50, z = 67;"

    "现在的血量是:100"

    优点

    • 封装细节,如果要更改保存的细节,也不会影响到客户端

    缺点

  • 相关阅读:
    Mastering Web Application Development with AngularJS 读书笔记-前记
    通过信息系统项目管理师-我的备考经验
    通过系统集成项目管理工程师考试-我的备考分享
    即将翻译 Building The New Financial Times Web App
    CSS3:flex布局应用
    前端性能利器——dynatrace ajax edition
    SIMD---AVX系列
    DirectSound---捕获音频、Qml/C++ 集成交互
    SIMD---SSE系列及效率对比
    SIMD---MMX代码优化
  • 原文地址:https://www.cnblogs.com/wzxNote/p/12809154.html
Copyright © 2020-2023  润新知