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

文章目录

  • 备忘录模式(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方法获取指定索引的备忘录,以便提供给原发器进行状态恢复操作,从而实现了游戏角色状态的保存与恢复功能,体现了备忘录模式的基本应用逻辑。

应用场景

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/942176.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WPS工具栏灰色怎么办

WPS离线不登录&#xff0c;开启工具栏等相关功能 当你在使用WPS的过程中&#xff0c;若因网络问题或其他特殊原因&#xff0c;导致无法登录使用WPS时&#xff0c;可根据以下步骤开启离线兼容模式&#xff0c;开启此模式后&#xff0c;可在未登录的状态下&#xff0c;激活并使用…

【C++基础】09、结构体

一、结构体(struct) C/C 数组允许定义可存储相同类型数据项的变量&#xff0c;但是结构体是 C 中另一种用户自定义的可用的数据类型&#xff0c;它允许存储不同类型的数据项。 结构体用于表示一条记录&#xff0c;假设现在想要跟踪图书馆中书本的动态&#xff0c;可能需要跟踪每…

安卓蓝牙扫描流程

目录 系统广播 流程图 源码跟踪 系统广播 扫描开启广播&#xff1a;BluetoothAdapter.ACTION_DISCOVERY_STARTED "android.bluetooth.adapter.action.DISCOVERY_STARTED";扫描关闭广播&#xff1a;BluetoothAdapter.ACTION_DISCOVERY_FINISHED "android.b…

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

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

如何查看pad的console输出,以便我们更好的进行调试,查看并了解实际可能的问题。

1、以下是baidu AI回复&#xff1a; 2、说明&#xff1a; 1&#xff09;如果小伙伴们经常做android开发的话&#xff0c;这个不陌生&#xff0c;因为调试都是要开启这个开发者模式。并启用USB调试模式。 2&#xff09;需要连上USB线&#xff0c;有的时候会忘记&#xff0c;然…

外贸企业需要部署SD-WAN专线吗?

随着外贸行业对互联网和数字化技术依赖的加深&#xff0c;网络质量已成为影响企业运营效率和竞争力的重要因素。本文将深入探讨SD-WAN专线如何助力外贸企业优化业务运营。 外贸企业面临的网络挑战 1. 跨国访问速度缓慢 在访问海外服务器或目标网站时&#xff0c;外贸企业常常遭…

MySQL什么情况下会导致索引失效

MySQL什么情况下会导致索引失效 索引&#xff08;Index&#xff09;是数据库中一种用于快速查找和访问表中数据的结构&#xff0c;它类似于书的目录&#xff0c;通过索引可以快速定位到目标数据&#xff0c;而无需遍历整个表&#xff0c;索引的存在可以显著提高查询速度&#x…

两分钟解决:vscode卡在设置SSH主机,VS Code-正在本地初始化VSCode服务器

问题原因 remote-ssh还是有一些bug的&#xff0c;在跟新之后可能会一直加载初始化SSH主机解决方案 1.打开终端2.登录链接vscode的账号&#xff0c;到家目录下3.找到 .vscode-server文件,删掉这个文件4.重启 vscode 就没问题了

uniapp登录

第一步整登录 先整个appid APPID和APPSecret https://developers.weixin.qq.com/community/develop/article/doc/000ca4601b8f70e379febac985b413 一个账号只能整一个小程序 正确流程 调用uni.login https://juejin.cn/post/7126553599445827621 https://www.jb51.net/a…

I.MX6U 启动方式详解

一、启动方式选择 BOOT 的处理过程是发生在 I.MX6U 芯片上电以后,芯片会根据 BOOT_MODE[1:0]的设置 来选择 BOOT 方式。 BOOT_MODE[1:0]的值是可以改变的,有两种方式,一种是改写 eFUSE(熔 丝),一种是修改相应的 GPIO 高低电平。第一种修改 eFUSE 的方式只能修改一次,后面就…

项目代码第6讲:UpdownController.cs;理解 工艺/工序 流程、机台信息;前端的“历史 警报/工艺 记录”;每个机台各个管道的数据(温度、压力、气体)

一、UpdownController.cs 1、前端传入 当用户在下图的“记录查询”中的 两个界面选项 中,点击“导出”功能时,向后端发起请求,请求服务器下载文件的权限 【权限是在Program.cs中检测的,这个控制器里只需要进行“谁在哪个接口下载了文件”的日志记录】 【导出:是用户把…

WebRTC搭建与应用(五)-Coturn踩坑记

WebRTC搭建与应用(五)-Coturn踩坑记 近期由于项目需要在研究前端WebGL渲染转为云渲染&#xff0c;借此机会对WebRTC等有了初步了解&#xff0c;在此记录一下&#xff0c;以防遗忘。 第五章 WebRTC搭建与应用(五)-Coturn踩坑记 文章目录 WebRTC搭建与应用(五)-Coturn踩坑记前…

JVM简介—3.JVM的执行子系统

大纲 1.Class文件结构 2.Class文件格式概述 3.Class文件格式详解 4.字节码指令 5.类的生命周期和初始化 6.类加载的全过程 7.类加载器 8.双亲委派模型 9.栈桢详解 11.方法调用详解 12.基于栈的字节码解释执行引擎 1.Class文件结构 (1)Java跨平台的基础 字节码是各…

将自定义或第三方库的jar包引入项目中

文章目录 1.背景2.实现 1.背景 个人项目中引入了某个免费版框架有字数限制&#xff0c;我们业务需要生成字数很多&#xff0c;超过了限制&#xff0c;现在要引入自定义的jar解决问题。 2.实现 在resource文件夹下建lib文件夹 (属于是约定)&#xff0c;将自己的jar包放入 然后…

STL格式转换为FBX格式

STL格式与FBX格式简介 STL&#xff08;Stereo Lithography&#xff09;文件是一种用于3D打印的文件格式。它是由3D Systems公司开发的一种二进制文件格式&#xff0c;用于立体光刻技术。 FBX格式支持多边形游戏模型、曲线、表面、点组材质。FBX文件格式支持所有主要的三维数据…

VMware虚拟机三种网络工作模式

vmware为我们提供了三种网络工作模式,它们分别是:Bridged(桥接模式)、NAT(网络地址转换模式)、Host-Only(仅主机模式)。 打开vmware虚拟机,我们可以在选项栏的“编辑”下的“虚拟网络编辑器”中看到VMnet0(桥接模式)、VMnet1(仅主机模式)、VMnet8(NAT模式),那…

AI 技术,让洗护行业焕然「衣」新

根据最新的 Location 数据显示&#xff0c;国内目前有 20.79 万家与洗衣服务相关的企业。其中超过 80% 仍然是传统的夫妻店模式&#xff0c;即前店收衣后店洗衣的小型洗衣店。这种模式通常规模较小&#xff0c;服务范围有限&#xff0c;主要依赖于店主的个人经营。 另外 20% 企…

Hadoop集群(HDFS集群、YARN集群、MapReduce​计算框架)

一、 简介 Hadoop主要在分布式环境下集群机器&#xff0c;获取海量数据的处理能力&#xff0c;实现分布式集群下的大数据存储和计算。 其中三大核心组件: HDFS存储分布式文件存储、YARN分布式资源管理、MapReduce分布式计算。 二、工作原理 2.1 HDFS集群 Web访问地址&…

HDR视频技术之十:MPEG 及 VCEG 的 HDR 编码优化

与传统标准动态范围&#xff08; SDR&#xff09;视频相比&#xff0c;高动态范围&#xff08; HDR&#xff09;视频由于比特深度的增加提供了更加丰富的亮区细节和暗区细节。最新的显示技术通过清晰地再现 HDR 视频内容使得为用户提供身临其境的观看体验成为可能。面对目前日益…

精准提升:从94.5%到99.4%——目标检测调优全纪录

&#x1f680; 目标检测模型调优过程记录 在进行目标检测模型的训练过程中&#xff0c;我们面对了许多挑战与迭代。从初始模型的训练结果到最终的调优优化&#xff0c;每一步的实验和调整都有其独特的思路和收获。本文记录了我在优化目标检测模型的过程中进行的几次尝试&#…