Chapter14:备忘录模式
备忘录(Memento)模式:
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
把保存的细节给封装在了Memento中了,任何时候要更改保存的细节也不用影响客户端了。
Memento模式比较适合用于功能比较复杂的,但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分时,Originator可以根据保存的Memento信息还原到前一状态。如果在某个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销操作的状态。使用备忘录可以把复杂的对象内部信息对其他的对象屏蔽起来。当角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态恢复。
实际应用(工程结构)
(1)发起人 GamePlayer.h
(2)备忘录 PlayerStateBackup.h
(3)管理者 PlayerStateManager.h
(4)客户端 MementoApp.cpp
(1)发起人 GamePlayer.h
#ifndef _GAME_PLAYER_H_
#define _GAME_PLAYER_H_
#include "PlayerStateBackup.h"
#include <string>
#include <iostream>
using namespace std;
class GamePlayer
{
public:
// 状态显示
void DisplayPlayerState()
{
cout << "当前角色状态:体力-" << m_nVIT << " 攻击力-" << m_nATK << " 防御力-" << m_nDEF << endl;
}
// 获取初始化状态。可通过本地磁盘或者远程数据库
void GetInistance()
{
m_nVIT = 100;
m_nATK = 100;
m_nDEF = 100;
}
// 被BOSS ASS-KICK
void AssKickByBoss()
{
m_nVIT = 1;
m_nATK = 2;
m_nDEF = 3;
cout << "\n当前角色被扁了……" << endl;
}
// 保存角色状态。将游戏角色的3种状态值通过实例化“PlayerStateBackup”返回
PlayerStateBackup* SavePlayerState()
{
return (new PlayerStateBackup(m_nVIT, m_nATK, m_nDEF));
}
// 恢复角色状态。可将外部的“PlayerStateBackup”中的状态值恢复给游戏角色
void RecoveryState(PlayerStateBackup* pState)
{
m_nVIT = pState->GetVIT();
m_nATK = pState->GetATK();
m_nDEF = pState->GetDEF();
cout << "\n玩家调用存档还原了角色状态!" << endl;
}
private:
int m_nVIT; // 生命力
int m_nATK; // 攻击力
int m_nDEF; // 防御力
};
#endif// _GAME_PLAYER_H_
(2)备忘录 PlayerStateBackup.h
#ifndef _PLAYER_STATE_BACKUP
#define _PLAYER_STATE_BACKUP
class PlayerStateBackup
{
public:
PlayerStateBackup(const int nVIT, const int nATK, const int nDEF)
: m_nVIT(nVIT)
, m_nATK(nATK)
, m_nDEF(nDEF)
{
}
// 生命力
void SetVIT(const int nVIT){ m_nVIT = nVIT; }
int GetVIT(void) { return m_nVIT; }
// 攻击力
void SetATK(const int nATK){ m_nATK = nATK; }
int GetATK(void) { return m_nATK; }
// 防御力
void SetDEF(const int nDEF){ m_nDEF = nDEF; }
int GetDEF(void) { return m_nDEF; }
private:
int m_nVIT; // 生命力
int m_nATK; // 攻击力
int m_nDEF; // 防御力
};
#endif// _PLAYER_STATE_BACKUP
(3)管理者 PlayerStateManager.h
#ifndef _PLAYER_STATE_MANAGER_H_
#define _PLAYER_STATE_MANAGER_H_
#include "PlayerStateBackup.h"
class PlayerStateManager
{
public:
PlayerStateBackup* GetPlayerBackup() { return m_pPlayerBackup; }
void SetPlayerBackup(PlayerStateBackup* pPlayerBackup) { m_pPlayerBackup = pPlayerBackup; }
private:
PlayerStateBackup* m_pPlayerBackup;
};
#endif// _PLAYER_STATE_MANAGER_H_
(4)客户端 MementoApp.cpp
// MementoApp.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "GamePlayer.h"
#include "PlayerStateManager.h"
void FreePtr(void* vPtr)
{
if (NULL != vPtr)
{
delete vPtr;
vPtr = NULL;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
// 与BOSS对战前
GamePlayer* pSuperMario = NULL;
pSuperMario = new GamePlayer();
if (NULL != pSuperMario)
{
pSuperMario->GetInistance();
pSuperMario->DisplayPlayerState();
}
// 保存进度。由于封装在PlayerStateBackup中,因此我们并不知道保存了哪些具体的角色数据
PlayerStateManager* pPlayerManager = NULL;
pPlayerManager = new PlayerStateManager();
if (NULL != pPlayerManager)
{
pPlayerManager->SetPlayerBackup(pSuperMario->SavePlayerState());
}
if (NULL != pSuperMario && NULL != pPlayerManager)
{
// 大战BOSS后超级玛丽快挂了…
pSuperMario->AssKickByBoss();
pSuperMario->DisplayPlayerState();
// 恢复之前的状态
pSuperMario->RecoveryState(pPlayerManager->GetPlayerBackup());
pSuperMario->DisplayPlayerState();
}
system("pause");
FreePtr(pPlayerManager);
FreePtr(pSuperMario);
return 0;
}