这个模式让我首先联想到的就是游戏存档,打boss或者不玩的时候,存个档,之后读档接着玩。而存档就相当于将数据存储到该存储的地方,而读档就是把数据读取出来。大部分游戏都是HP、MP、攻击力和生命值,而从开发角度看,你角色本身具有这些属性,而存档时存的数据也需要存储这些属性,这就相当于有一个模板,里面都是各种数据,然后你的角色拷贝了一份,然后显示出来;而存档,经常存到第三方,如文件、数据库等等。存档、读档的操作是角色(玩家)所具备的一个功能,所以存档就是角色提供一个方法,把自身的数据输入到存档模板里面,然后放到该放的地方去,而备忘录模式,就是不破坏数据和封装性的前提下,将一个对象(角色)的内部状态进行外部存储,并且可以回复存储时的状态。
Originator:就是你所控制的角色对象,存储许多数据,比如血量等等,并且需要提供save和load两个接口,以便进行存档和读档操作,而且在游戏进行过程中,这个对象就是进行个中交互的对象,比如血量增加等等
Memento:存储模板,简单来说就是数据存储的临时对象(对象某个情况下的内部状态),当你存档的时候,会将需要存档的数据写到一个该对象中,然后通过服务器或者管理系统,将该对象存储到该存储的地方
Caretaker:管理者,负责保存备忘录,不可对其内容进行修改或检查,简单来说就是游戏公司不可随意修改存档。
使用场景:
需要保存和回复数据的场景提供回滚或者上一步、上几步的功能优点:
提供回档机制,避免失误操作实现数据封装,用户不需要了解存档和读档细节缺点:
保存的数据几乎时克隆出一个独立数据,大部分时间存储在内存中,如果数据过大,可能造成内存过高
实操
注:在实现的过程中,可以认为的区分一些临时和存档数据,这样在存档数据的类中可能就可以减少一些数据的存储。
思维实现:
设计实现CSaveData数据模板,先实现该类,确定需要存储的数据实现角色类,将所有需要显示或者使用到的数据存储进行定义实现Save和Read函数,将需要存储的数据进行存档和读档操作实现管理类,管理类只能负责存储和读取数据,没有外部接口可以操作和检查数据 // MemorandumModel.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <iostream> using namespace std; //存档数据 class CSaveData { private: int m_healthPoint; int m_manaPoint; int m_attackValue; int m_defenseValue; public: CSaveData() {} CSaveData(int health, int mana, int attack, int defense) { m_healthPoint = health; m_manaPoint = mana; m_attackValue = attack; m_defenseValue = defense; } int getHealthPoint() { return m_healthPoint; } void setHealthPoint(int value) { m_healthPoint = value; } int getManaPoint() { return m_manaPoint; } void setManaPonit(int value) { m_manaPoint = value; } int getAttackValue() { return m_attackValue; } void setAttackValue(int value) { m_attackValue = value; } int getDefenseValue() { return m_defenseValue; } void setDefenseValue(int value) { m_defenseValue = value; } }; class CRole { private: int m_healthPoint; int m_manaPoint; int m_attackValue; int m_defenseValue; public: CRole() { m_healthPoint = 100; m_manaPoint = 100; m_attackValue = 10; m_defenseValue = 10; } // //....数值set和get // void setHealthPoint(int value) { m_healthPoint = value; } //存档 CSaveData* saveRoleData() { return new CSaveData(m_healthPoint, m_manaPoint, m_attackValue, m_defenseValue); } //读档 void readRoleData(CSaveData* data) { m_healthPoint = data->getHealthPoint(); m_manaPoint = data->getManaPoint(); m_attackValue = data->getAttackValue(); m_defenseValue = data->getDefenseValue(); } // void show() { cout << "HP :"<<m_healthPoint<<endl; cout << "MP :"<<m_manaPoint<<endl; cout << "Attack :"<<m_attackValue<<endl; cout << "Defense:"<<m_defenseValue<<endl; } }; class CRoleDataManager { private: CSaveData* m_roleData; public: CSaveData* getSaveData() { return m_roleData; } void setSaveData(CSaveData* data) { m_roleData = data; } }; int main() { CRole *role = new CRole(); cout << "=============初始状态====================" << endl; role->show(); //保存 CRoleDataManager* data = new CRoleDataManager(); data->setSaveData(role->saveRoleData()); //升级 role->setHealthPoint(1000); cout << "=============升级了,属性变化:==========" << endl; role->show(); //回档 role->readRoleData(data->getSaveData()); cout << "============开挂,被回档=================" << endl; role->show(); }