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

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

游戏存进度

//GameRole.h 游戏角色类
#pragma execution_character_set("utf-8")
#include <QDebug>

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;
    }
};
//main.cpp 客户端代码
#include "GameRole.h"
#include <memory>

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

运行结果:

"角色当前状态:"
"体力:100"
"攻击力:100"
"防御力:100"

"角色当前状态:"
"体力:0"
"攻击力:0"
"防御力:0"

"角色当前状态:"
"体力:100"
"攻击力:100"
"防御力:100"

备忘录模式基本代码

在这里插入图片描述

//Originator.h 发起人类
#include <QString>
#include <memory>
#include <QDebug>
#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;
    }
};
//Memento.h 备忘录类
#include <QString>

class Memento
{
private:
    QString m_state;
public:
    Memento(QString state) : m_state(state) {}
    QString getState() {
        return m_state;
    }
};
//Caretaker.h 管理者类
#include "Memento.h"
#include <memory>

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;
    }
};
//main.cpp 客户端代码
#include <memory>
#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;
}

运行结果:

"State = On"
"State = Off"
"State = On"

游戏进度备忘

在这里插入图片描述

//GameRole.h 游戏角色类增加的内容
#include "RoleStateMemento.h"
#include <memory>

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();
    }
    //...
};
//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;
    }
};
//RoleStateCaretaker.h 角色状态管理者
#include <memory>
#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;
    }
};
//main.cpp 客户端代码
#include "GameRole.h"
#include <memory>
#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;
}

运行结果:

"角色当前状态:"
"体力:100"
"攻击力:100"
"防御力:100"

"角色当前状态:"
"体力:0"
"攻击力:0"
"防御力:0"

"角色当前状态:"
"体力:100"
"攻击力:100"
"防御力:100"

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

在这里插入图片描述

要点总结

  • 备忘录(Memento)存储原发器(Originator)对象的内部状态在需要时恢复原发器状态。
  • Memento模式的核心是信息隐藏,即Originator需要向外界隐藏信息,保持其封装性。但同时又需要将状态保持到外界(Memento)。
  • 由于现代语言运行时(如C#、Java等)都具有相当的对象序列化支持,因此往往采用效率较高、有较容易正确实现的序列化方案来实现Memento模式。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值