您的位置:首页 > 编程语言 > C语言/C++

【重读设计模式】备忘录模式

2014-10-25 23:08 323 查看
玩过单机游戏的人都知道,一般单机游戏都有存储当前进度或者叫做存档的概念,存档的意思就是将当前你的任务状态保存下来,以后你可以再将该存档给打开,从而使游戏从这里开始玩起,如果不存档那么游戏每次都是从最开始玩起。网络游戏更是如此,游戏内角色的状态都会不断的被记录,如果用户下线或者死机从先上线后都会是最新的状态而不至于会被丢失。其实这里的存档就是备忘,我们通过备忘录模式将对象的信息从内存中固化下来。就好像现实生活中会议中的结论,我们需要用笔记下来然后发送邮件通知进行备忘一样,只不过这里是从脑子中将结论写下来备忘,程序是从内存中备份到持久介质中(一般是磁盘)。

从上面可知,备忘录模式是较为常用的一种模式,实际上只要一个系统使用到了对象的类似回滚、比较、相对的算法时,都可能需要使用备忘录模式。

定义:在不破坏封装的前提下,捕获一个对象的内部状态,并在这个对象之外保存这个状态,这样就可以在以后某个时刻将该对象恢复到该状态,备忘录模式也叫快照模式,用一句比较诗意的话说“如果再回到从前”。

定义解释:就好像前面将的单机游戏的存档例子,用户在打一个大boss之前都会存档,因为如果挑战失败了正常情况下游戏需要从新开始,但是那样需要耗时很久。如果我们先将当前的进度保存好,就算这次失败下次我们直接从现在的进度开始则大大缩短了时间。这个存档就是获取了当前游戏的内部状态(包括进度和人物属性),当用户需要恢复的时候直接加载这个存档即可,这个加载的过程就是恢复对象的过程。

类图:



例子:

还是使用游戏的存储进度为例子

设计:

我们使用Memento表示需要存储的角色信息,假设我们简单的只存储用户的状态信息,包括位置、等级、生命、攻击力、防御力、移动速度等,那么在CMemento中有用户角色的这些值,我们定义ROLE_ITEMS结构来存储这些内容,CMemento中有一个ROLE_ITEMS的成员。我们定义original表示游戏角色管理类,该类可以获取游戏所有的信息,我们定义Caretake用于外部存储角色状态信息Memento。

实现:

//============================================================================

// Name        : memento.cpp

// Author      : tester

// Version     :

// Copyright   : Your copyright notice

// Description : Hello World in C++, Ansi-style

//============================================================================

#include <iostream>

using namespace std;

class Memento

{

public:
int level;
int life;
int attack;
int defense;
int speed;

public:
Memento()
{
level = 0;
life = 0;
attack = 0;
defense = 0;
speed = 0;
}

Memento(const int level, const int life, const int attack, const int defense, const int speed)
{
this->level = level;
this->life = life;
this->attack = attack;
this->defense = defense;
this->speed = speed;
}

void operator=(const Memento& other)
{
level = other.level;
life = other.life;
attack = other.attack;
defense = other.defense;
speed = other.speed;
}

};

class Caretake

{

public:
Caretake()
{
;
}

void save_memento(const Memento& role)
{
m_role = role;
}

Memento last_memento()
{
return m_role;
}

private:
Memento m_role;

};

class Original

{

public:
Original()
{
level = 0;
life = 0;
attack = 0;
defense = 0;
speed = 0;
}

void set_level(const int level)
{
this->level = level;
}

void set_life(const int life)
{
this->life = life;
}

void set_attack(const int attack)
{
this->attack = attack;
}

void set_defense(const int defense)
{
this->defense = defense;
}

void set_speed(const int speed)
{
this->speed = speed;
}

void show()
{
cout << "level=" << level << " ";
cout << "life=" << life << " ";
cout << "attack=" << attack << " ";
cout << "defense=" << defense << " ";
cout << "speed=" << speed << endl;
}

Memento save()
{
Memento role(level, life, attack, defense, sp
4000
eed);
return role;
}

void restore(const Memento& role)
{
this->level = role.level;
this->life = role.life;
this->attack = role.attack;
this->defense = role.defense;
this->speed = role.speed;
}

private:
int level;
int life;
int attack;
int defense;
int speed;

};

int main() {
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!

Original onerole;
onerole.set_level(100);
onerole.set_life(1000);
onerole.set_attack(78);
onerole.set_defense(9);
onerole.set_speed(123);

cout << "初始状态:" << endl;
onerole.show();

//存储
Memento store_role = onerole.save();
Caretake caretake;
caretake.save_memento(store_role);

onerole.set_level(120);
onerole.set_attack(91);
onerole.set_defense(11);

cout << "改变后的状态:" << endl;
onerole.show();

Memento last_role = caretake.last_memento();
onerole.restore(last_role);

cout << "恢复后的状态:" << endl;
onerole.show();

return 0;

}

运行结果:

!!!Hello World!!!

初始状态:

level=100 life=1000 attack=78 defense=9 speed=123

改变后的状态:

level=120 life=1000 attack=91 defense=11 speed=123

恢复后的状态:

level=100 life=1000 attack=78 defense=9 speed=123

总结:备忘录模式提供了一种在外部存储对象内部状态的方法,使用该方法可以不破坏对象封装的情况下在对象外部存储对象状态。并在需要的时候将从外部导入对象的状态,从而使对象还原,就好像回到了当初一样。备忘录模式在系统的设计中经常使用,尤其是涉及到要回滚、比较等系统中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设计模式 c++ 备份