设计模式_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 使用场景

需要保存和恢复数据的场景。
需要提供一个可回滚操作的场景。

return 设计模式概述;

返回设计模式概述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值