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

server/2024/12/24 9:16:55/

文章目录

  • 备忘录模式(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.ppmy.cn/server/152733.html

相关文章

[计算机网络]OSPF协议

开放最短路径优先OSPF 1&#xff09;OSPF的工作方式 1>和谁交换消息 使用洪泛法&#xff0c;向本自治系统的所有路由器发送消息。 2>交换什么消息 发送的消息就是与本路由器相邻的所有路由器的链路状态&#xff0c;但这只是路由器所知道的部分信息。 链路状态就是说…

详解大模型多轮对话的输入和输出token序列

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于大模型算法的研究与应用。曾担任百度千帆大模型比赛、BPAA算法大赛评委,编写微软OpenAI考试认证指导手册。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。授权多项发明专利。对机器学…

面试题整理13----deployment和statefulset区别

面试题整理13----deployment和statefulset区别 1. Deployment2. StatefulSet3. 总结 Deployment 和 StatefulSet 是 Kubernetes 中两种常用的工作负载资源&#xff0c;它们都可以用来部署和管理 Pod 1. Deployment 无状态应用&#xff1a;Deployment 主要用于部署无状态的应用…

面试题整理4----lvs,nginx,haproxy区别和使用场景

LVS、Nginx、HAProxy&#xff1a;区别与使用场景 1. LVS&#xff08;Linux Virtual Server&#xff09;1.1 介绍1.2 特点1.3 使用场景 2. Nginx2.1 介绍2.2 特点2.3 使用场景 3. HAProxy3.1 介绍3.2 特点3.3 使用场景 4. 总结对比 在构建高可用、高性能的网络服务时&#xff0c…

Linux 下的 GPT 和 MBR 分区表详解

文章目录 Linux 下的 GPT 和 MBR 分区表详解一、分区表的作用二、MBR&#xff08;Master Boot Record&#xff09;1. **特点**2. **优点**3. **缺点**4. **适用场景** 三、GPT&#xff08;GUID Partition Table&#xff09;1. **特点**2. **优点**3. **缺点**4. **适用场景** 四…

智尚招聘求职小程序V1.0.18

微信小程序招聘管理系统。支持多城市、人才版块、招聘会、职场资讯、经纪人入驻等功能。提供全部无加密源码&#xff0c;支持私有化部署。 V1.0.18增加功能与修复一些BUG 1、增加过审机制(后台系统设置里开启)2、增加后台经纪派遣人才管理3、优化前端经纪派遣人功能4、修复前…

Redis Hash Tag 知识详解

一、Redis Hash Tag概述 Redis Hash Tag是Redis集群环境里用于控制数据分片的关键机制。在Redis集群中&#xff0c;数据依据键的哈希值来确定分片存储位置。Hash Tag能让用户指定键的特定部分作为哈希计算核心部分&#xff0c;进而使相关键存储于同一节点&#xff0c;这对处理…

基于指纹图像的数据隐藏和提取matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 matlab2022a 3.部分核心程序 &#xff08;完整版代码包含详细中文注释和操作步骤视频&#xff09…