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

news/2024/12/26 15:34:57/

文章目录

  • 备忘录模式(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/news/1558299.html

相关文章

3D视觉坐标变换(像素坐标转换得到基于相机坐标系的坐标)

在图像处理中,我们经常得到目标的坐标是像素坐标,需要将其转换到相机坐标系下的实际物理坐标。 使用场景:根据深度学习模型,已经完成了目标检测,使用3D相机,得到目标在图像中的像素坐标和深度信息,需要将2D图像中得到的像素坐标,利用深度图计算出对应目标在空间中的位姿…

AJAX与Axios

什么是 AJAX ? AJAX 是异步的 JavaScript 和 XML&#xff08;Asynchronous JavaScript And XML&#xff09;。 简单理解AJAX&#xff1a;是一种客户端与服务器进行网络通信技术&#xff0c;AJAX通常使用XMLHttpRequest 对象来发送请求和接收响应 现代开发中我们通常使用 JS…

什么是Web极简架构

极其简单Web架构&#xff08;radically simple web&#xff09;是一个面向初创企业和小型企业的 Web 应用程序蓝图&#xff1a;何使用 模块化单体Modular Monoliths、SSR、微前端Micro Frontends、HTMX 和 Tailwind CSS 跨多个领域团队构建 Web 应用程序。 本文为运行或构建跨…

「下载」智慧产业园区-数字孪生建设解决方案:重构产业全景图,打造虚实结合的园区数字化底座

数字孪生技术作为一种创新的管理工具&#xff0c;正逐步展现出其在智慧园区建设中的重要意义。以下将从几个方面详细阐述数字孪生在智慧园区建设中的关键作用。 一、提升园区运营管理的智能化水平 数字孪生技术通过构建园区的虚拟镜像&#xff0c;实现了对园区物理世界的全面…

Unable to create data directory /var/lib/zookeeper/log/version-2

Unable to create data directory /var/lib/zookeeper/log/version-2 测试环境出现了这个问题&#xff0c;一开始是另外一个问题zookeeper无法写入日志&#xff0c;我以为坏掉了&#xff0c;就用docker rm&#xff0c; 然后docker run重新启动 结果还是不行&#xff0c;就把这…

(Arxiv-2024)SwiftEdit:通过一步扩散实现闪电般快速的文本引导图像编辑

SwiftEdit&#xff1a;通过一步扩散实现闪电般快速的文本引导图像编辑 Paper是VinAI Research发表在Arxiv2024的工作 Paper Title:SwiftEdit: Lightning Fast Text-Guided Image Editing via One-Step Diffusion Code地址 Abstract 文本引导的图像编辑方面的最新进展利用了基于…

【学习总结|DAY023】Java高级技术

大家好&#xff0c;今天我们来聊聊 Java 中的几个高级技术&#xff1a;单元测试、反射、注解和动态代理。这些技术在源码、框架和架构师层面发挥着重要作用&#xff0c;掌握它们能让我们更深入地理解 Java 的底层原理&#xff0c;并提升代码质量和开发效率。 单元测试&#xf…

基于微信小程序的在线选课系统springboot+论文源码调试讲解

第2章 开发环境与技术 基于web的在线选课系统的编码实现需要搭建一定的环境和使用相应的技术&#xff0c;接下来的内容就是对基于web的在线选课系统用到的技术和工具进行介绍。 2.1 MYSQL数据库 本课题所开发的应用程序在数据操作方面是不可预知的&#xff0c;是经常变动的&a…