重拾设计模式--备忘录模式

news/2024/12/22 18:12:11 标签: 设计模式, 备忘录模式, 数据库

文章目录

  • 备忘录模式(Memento Pattern)概述
    • 定义:
  • 作用:
    • 实现状态的保存与恢复
    • 支持撤销 / 恢复操作
  • 备忘录模式UML图
  • 备忘录模式的结构
    • 原发器(Originator):
    • 备忘录(Memento):
    • 负责人(Caretaker):
  • C++ 代码示例
  • 应用场景

备忘录模式(Memento Pattern)概述

定义:

备忘录模式是一种行为型设计模式,它用于在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便之后可以将对象恢复到原先保存的状态。简单来说,就像是给对象的某个时刻的状态拍个 “快照”,之后可以根据这个 “快照” 让对象回到当时的样子。

作用:

实现状态的保存与恢复

在很多应用场景中,对象的状态会不断变化,但有时候需要能够回退到之前的某个状态。例如,在文本编辑器中,用户进行了一系列的编辑操作(输入文字、删除内容、修改格式等)后,可能希望撤销到之前的某个版本,备忘录模式就能很好地实现这种状态的记录与恢复功能。

支持撤销 / 恢复操作

为用户提供方便的撤销和恢复操作机制,提升用户体验。像在图形绘制软件中,绘制了多个图形后,若想撤销上一步操作或者恢复之前误撤销的操作,借助备忘录模式记录图形绘制过程中的状态变化,就可以轻松达成。
隔离状态的保存与使用:将对象状态的保存和恢复逻辑与对象本身的业务逻辑分离开来,使得对象的核心功能不会因为要处理状态记录等操作而变得复杂,同时也便于对状态管理部分进行独立的扩展和维护。

备忘录模式UML图

在这里插入图片描述

备忘录模式的结构

原发器(Originator):

它是需要被保存状态的对象,创建并管理备忘录对象。它可以创建一个备忘录来记录当前自身的状态,也能够从备忘录中恢复自己之前的状态,通常包含一些表示其内部状态的属性以及创建和恢复状态的方法。

备忘录(Memento):

用于存储原发器对象的内部状态,它的内部结构通常对原发器的状态进行了封装,外部对象一般不能直接访问备忘录的内部状态,只能通过原发器来间接操作,以此来保证状态的封装性和安全性。

负责人(Caretaker):

负责保存备忘录对象,但不负责对备忘录内容进行操作,只是单纯地管理备忘录的存储和获取等。例如,可以将备忘录对象保存在一个列表中,以便按照一定顺序来提供给原发器进行状态恢复操作。

C++ 代码示例

以下以一个简单的游戏角色状态保存与恢复的例子来展示备忘录模式的代码实现。假设游戏角色有生命值(health)和魔法值(mana)两个属性,我们希望能保存和恢复角色的状态。

#include <iostream>
#include <vector>

// 备忘录类,用于保存游戏角色的状态
class Memento 
{
private:
	int health;
	int mana;
public:
	Memento(int health, int mana) : health(health), mana(mana) {}
	int getHealth() const 
	{
		return health;
	}
	int getMana() const 
	{
		return mana;
	}
};

// 原发器类,游戏角色
class GameCharacter
{
private:
	int health;
	int mana;
public:
	GameCharacter() : health(100), mana(50) {}
	// 创建备忘录,保存当前角色状态
	Memento createMemento()
	{
		return Memento(health, mana);
	}
	// 从备忘录中恢复角色状态
	void restoreMemento(const Memento& memento)
	{
		health = memento.getHealth();
		mana = memento.getMana();
	}
	void takeDamage(int damage)
	{
		health -= damage;
		if (health < 0) health = 0;
	}
	void useMana(int cost)
	{
		mana -= cost;
		if (mana < 0) mana = 0;
	}
	void displayStatus()
	{
		std::cout << "Health: " << health << ", Mana: " << mana << std::endl;
	}
};

// 负责人类,管理备忘录
class Caretaker
{
private:
	std::vector<Memento> mementos;
public:
	void addMemento(const Memento& memento)
	{
		mementos.push_back(memento);
	}
	Memento getMemento(int index) 
	{
		return mementos[index];
	}
};

int main()
{
	GameCharacter character;
	Caretaker caretaker;

	character.displayStatus();

	// 保存初始状态
	caretaker.addMemento(character.createMemento());

	character.takeDamage(20);
	character.useMana(10);
	character.displayStatus();

	// 恢复到初始状态
	character.restoreMemento(caretaker.getMemento(0));
	character.displayStatus();

	return 0;
}

在上述代码中:
Memento类是备忘录,它内部有成员变量来保存游戏角色的生命值和魔法值状态,并且提供了获取这些状态的方法,但外部无法直接修改其内部状态。
GameCharacter是原发器,它有表示自身状态的生命值和魔法值属性,通过createMemento方法可以创建备忘录保存当前状态,通过restoreMemento方法能从备忘录中恢复状态,还有改变自身状态的相关操作方法(如takeDamage和useMana)。
Caretaker是负责人,它使用std::vector来存储备忘录对象,通过addMemento方法添加备忘录,通过getMemento方法获取指定索引的备忘录,以便提供给原发器进行状态恢复操作,从而实现了游戏角色状态的保存与恢复功能,体现了备忘录模式的基本应用逻辑。

应用场景

文本编辑器:在文本编辑器中,每一次用户输入、删除、修改文本格式等操作后,都可以使用备忘录模式记录文档的当前状态,实现撤销和恢复功能,方便用户纠正操作失误或者回退到之前满意的文档版本。
图形绘制软件:当用户绘制图形、移动图形、改变图形属性等操作时,利用备忘录模式保存图形界面的各个阶段的状态,这样可以支持撤销上一步操作、恢复之前的图形布局等功能,提升用户操作的灵活性。
数据库事务管理:在数据库操作中,事务的回滚机制可以看作是备忘录模式的一种应用。在事务执行过程中,会记录下操作前数据库的状态(相当于创建备忘录),如果事务执行过程中出现错误或者需要取消操作,就可以根据记录的状态(通过备忘录恢复)让数据库回到事务开始前的状态,保证数据的一致性。
游戏存档与读档:除了上述示例中的游戏角色状态保存与恢复,整个游戏的存档和读档功能也常借助备忘录模式。游戏过程中的各种游戏元素(角色状态、地图信息、任务进度等)的状态都可以被保存下来(创建备忘录),玩家之后可以从存档点读取之前保存的状态(恢复备忘录)继续游戏。


http://www.niftyadmin.cn/n/5795686.html

相关文章

Pytorch | 利用MI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击

Pytorch | 利用MI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击 CIFAR数据集MI-FGSM介绍背景算法原理 MI-FGSM代码实现MI-FGSM算法实现攻击效果 代码汇总mifgsm.pytrain.pyadvtest.py 之前已经针对CIFAR10训练了多种分类器&#xff1a; Pytorch | 从零构建AlexNet对CIFAR10进行…

sqlserver新建用户并分配对视图的只读权限

1、--创建了一个数据库角色&#xff0c;名称为:[seeview] exec sp_addrole seeview 2、--指定可查看的视图 GRANT SELECT ON view_getInventoryInfo TO seeview --GRANT SELECT ON view_getInventoryInfo2 TO seeview 3、--添加只允许访问指定视图的用户: exec sp_addlogin ‘登…

Type-C接口电热毯方案

Type-C接口电热毯是一种结合了最新科技元素的取暖产品&#xff0c;它将Type-C接口技术应用于电热毯上&#xff0c;为用户带来了更加便捷、安全、智能的取暖体验。以下是对Type-C接口电热毯的详细介绍&#xff1a; 一、Type-C接口的特点 Type-C接口是一组对称的连接器&#xff…

机器学习系列(一)——K-近邻算法

1. 算法定义 KNN 算法属于基于实例的机器学习方法。在对未知数据进行分类或回归之前&#xff0c;我们不需要对数据进行显式的训练或建立复杂的模型。它的核心思想是&#xff1a;对一个新的样本点&#xff0c;寻找在特征空间上与其最相似的 K 个已知数据点&#xff0c;采取“投…

重拾设计模式--外观模式

文章目录 外观模式&#xff08;Facade Pattern&#xff09;概述定义 外观模式UML图作用 外观模式的结构C 代码示例1C代码示例2总结 外观模式&#xff08;Facade Pattern&#xff09;概述 定义 外观模式是一种结构型设计模式&#xff0c;它为子系统中的一组接口提供了一个统一…

JAVA队列每次添加需要新实例才能独立更新

JAVA队列每次添加需要新实例才能独立更新 队列里面的实例多次添加同一个实例实例结果 每次添加一个新实例实例结果 队列中添加包装类型实例结果 队列里面的实例 由于JAVA对于Object类型参数传参传递的是地址&#xff0c;实例更新&#xff0c;队列里面的实例也会被更新。关于JA…

常用的JVM启动参数有哪些?

大家好&#xff0c;我是锋哥。今天分享关于【常用的JVM启动参数有哪些?】面试题。希望对大家有帮助&#xff1b; 常用的JVM启动参数有哪些? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 JVM启动参数用于配置Java虚拟机&#xff08;JVM&#xff09;的运行时行为…

从Windows远程访问Linux上的数据库

从Windows远程访问Linux上的数据库 目录 简介在Linux上安装MySQL/MariaDB配置MySQL/MariaDB以允许远程连接 修改MySQL/MariaDB配置文件重启MySQL/MariaDB服务确保防火墙允许MySQL/MariaDB端口 创建远程访问用户授予用户权限测试远程连接 检查网络连通性使用图形化工具连接 创…