设计模式_24 备忘录模式
24 备忘录模式
24.1 概念
存档,撤销。
在不破坏封装性的前提下捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时,能将该对象恢复到原先保存的状态。
24.2 结构
发起人角色:记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,可以访问备忘录里的所有信息。
备忘录角色:负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。
管理者角色:对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问和修改。
备忘录的两个等效接口:
窄接口:管理者对象(和其他发起人对象之外的任何对象)看到的是备忘录的窄接口,该接口只允许他把备忘录对象传给其他对象。
宽接口:发起人对象可以看到宽接口,该接口允许他读取所有数据,以便根据这些数据恢复这个发起人对象的内部状态
24.3 实现
24.3.1 白箱备忘录模式
备忘录角色对任何对象都提供一个接口,即宽接口,备忘录角色内部存储的状态对所有对象公开。
24.3.1.1 UML图

24.3.1.2 代码
#include<iostream>
#include<string>
using namespace std;
class RoleMemorandum {
private:
int level;
int time;
string package;
public:
RoleMemorandum(int level, int time, string package) : level(level), time(time), package(package) {}
int getLevel() {
return this->level;
}
int getTime() {
return this->time;
}
string getPackage() {
return this->package;
}
};
class GameRole {
private:
int level;
int time;
string package;
public:
void initState() {
this->level = 0;
this->time = 0;
this->package.clear();
}
void play() {
this->level++;
this->time++;
this->package += "不朽盾 ";
}
RoleMemorandum* saveState() {
RoleMemorandum* roleMemorandum = new RoleMemorandum(this->level, this->time, this->package);
return roleMemorandum;
}
void recoverState(RoleMemorandum* roleMemorandum) {
this->level = roleMemorandum->getLevel();
this->time = roleMemorandum->getTime();
this->package = roleMemorandum->getPackage();
}
void showState() {
cout << "等级:" << this->level << endl;
cout << "游戏时长:" << this->time << endl;
cout << "背包:" << this->package << endl;
cout << endl;
}
};
class RoleCaretaker {
private:
RoleMemorandum* roleMemorandum;
public:
RoleMemorandum* getRoleMemorandum() {
return this->roleMemorandum;
}
void setRoleMemorandum(RoleMemorandum* roleMemorandum) {
this->roleMemorandum = roleMemorandum;
}
};
int main() {
RoleCaretaker* roleCaretaker = new RoleCaretaker();
GameRole* role = new GameRole();
//初始化
role->initState();
role->showState();
//保存参数
roleCaretaker->setRoleMemorandum(role->saveState());
//进行游戏
role->play();
role->showState();
//回档
role->recoverState(roleCaretaker->getRoleMemorandum());
role->showState();
return 0;
}
24.3.2 黑箱备忘录模式
备忘录角色对发起人对象提供一个宽接口,而对其他对象提供一个窄接口。
实现方法:将备忘录类设计成发起人类的内部成员类。
24.3.2.1 UML图

24.3.2.2 代码
#include<iostream>
#include<string>
using namespace std;
class Memorandum {
};
class GameRole {
private:
int level;
int time;
string package;
// GameRole 的内部类 RoleMemorandum
class RoleMemorandum : public Memorandum {
private:
int level;
int time;
string package;
public:
RoleMemorandum(int level, int time, string package) : level(level), time(time), package(package) {}
int getLevel() {
return this->level;
}
int getTime() {
return this->time;
}
string getPackage() {
return this->package;
}
};
public:
void initState() {
this->level = 0;
this->time = 0;
this->package.clear();
}
void play() {
this->level++;
this->time++;
this->package += "不朽盾 ";
}
RoleMemorandum* saveState() {
RoleMemorandum* roleMemorandum = new RoleMemorandum(this->level, this->time, this->package);
return roleMemorandum;
}
void recoverState(Memorandum* memorandum) {
RoleMemorandum* roleMemorandum = (RoleMemorandum*)memorandum; //需要强制类型转换
this->level = roleMemorandum->getLevel();
this->time = roleMemorandum->getTime();
this->package = roleMemorandum->getPackage();
}
void showState() {
cout << "等级:" << this->level << endl;
cout << "游戏时长:" << this->time << endl;
cout << "背包:" << this->package << endl;
cout << endl;
}
};
class RoleCaretaker {
private:
Memorandum* memorandum;
public:
Memorandum* getMemorandum() {
return this->memorandum;
}
void setMemorandum(Memorandum* memorandum) {
this->memorandum = memorandum;
}
};
int main() {
RoleCaretaker* roleCaretaker = new RoleCaretaker();
GameRole* role = new GameRole();
//初始化
role->initState();
role->showState();
//保存参数
roleCaretaker->setMemorandum(role->saveState());
//进行游戏
role->play();
role->showState();
//回档
role->recoverState(roleCaretaker->getMemorandum());
role->showState();
return 0;
}
24.4 优缺点
24.4.1 优点
提供了一种可以恢复状态的机制,当用户需要时能够比较方便的将数据恢复到某个历史状态。
实现了内部状态的封装,除了创建他的发起人之外,其他对象都不能访问这些装态信息。
简化了发起人类。发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中并由管理者进行管理,符合单一职责原则。
24.4.2 缺点
资源消耗大,如果要保存的内部状态信息过多或者特别频繁,内存资源占用大。
24.5 使用场景
需要保存和恢复数据的场景。
需要提供一个可回滚操作的场景。
本文详细介绍了备忘录模式的概念、结构及两种实现方式——白箱和黑箱备忘录模式。备忘录模式用于在不破坏封装的前提下,保存对象的内部状态,以便于恢复。通过示例代码展示了如何在游戏角色类中应用备忘录模式,实现游戏状态的保存和回档。此外,还讨论了备忘录模式的优缺点和适用场景。
3009

被折叠的 条评论
为什么被折叠?



