【设计模式-备忘录】

备忘录模式(Memento Pattern)是一种行为型设计模式,用于保存对象的内部状态,以便在将来某个时间可以恢复到该状态,而不暴露对象的内部实现细节。备忘录模式特别适合在需要支持撤销(Undo)操作的应用中。

定义

在不破坏封装的前提下,捕获对象的内部状态,并在对象之外保存这个状态,以便日后能将对象恢复到原先保存的状态。

UML图

在这里插入图片描述
备忘录模式涉及的角色:

  • Originator(发起者):负责创建备忘录对象,用来记录自己的内部状态,并可以根据备忘录恢复状态。
  • Memento(备忘录):存储发起者的内部状态,防止对象的内部状态泄露。通常只允许发起者访问其内部状态。
  • Caretaker(负责人):负责保存备忘录对象,但不能对备忘录的内容进行操作或访问。

代码

import java.util.ArrayList;
import java.util.List;// 发起者类
class Originator {private String state;// 设置状态public void setState(String state) {this.state = state;System.out.println("当前状态: " + state);}// 保存当前状态到备忘录public Memento saveStateToMemento() {return new Memento(state);}// 从备忘录中恢复状态public void getStateFromMemento(Memento memento) {state = memento.getState();System.out.println("恢复到状态: " + state);}// 备忘录类public static class Memento {private final String state;public Memento(String state) {this.state = state;}public String getState() {return state;}}
}// 负责人类
class Caretaker {private final List<Originator.Memento> mementoList = new ArrayList<>();// 添加备忘录public void add(Originator.Memento state) {mementoList.add(state);}// 获取备忘录public Originator.Memento get(int index) {return mementoList.get(index);}
}// 测试类
public class MementoPatternDemo {public static void main(String[] args) {Originator originator = new Originator();Caretaker caretaker = new Caretaker();// 保存状态originator.setState("状态1");caretaker.add(originator.saveStateToMemento());originator.setState("状态2");caretaker.add(originator.saveStateToMemento());originator.setState("状态3");caretaker.add(originator.saveStateToMemento());// 恢复状态originator.getStateFromMemento(caretaker.get(1)); // 恢复到状态2originator.getStateFromMemento(caretaker.get(0)); // 恢复到状态1}
}

场景

1. 撤销/恢复操作

在需要支持“撤销(Undo)”和“恢复(Redo)”的应用中,备忘录模式非常适用。每当状态发生变化时,可以保存一个备忘录对象,用户可以在需要时撤销操作,恢复到之前的状态。
应用场景:

  • 文本编辑器:例如,在文本处理软件中,用户进行编辑时,每次输入、删除或格式化操作都改变文档的状态。通过备忘录模式,用户可以撤销某些操作,并恢复到之前的编辑状态。
  • 绘图软件:绘图过程中每一步的修改都可能需要撤销或恢复。

2. 保存历史状态

当需要记录一个对象的历史状态,并在将来某一时刻恢复特定状态时,备忘录模式是一个合适的选择。这样可以在不破坏对象封装性的前提下保存状态。

应用场景:

  • 版本控制系统:在版本控制中,每次保存都会存储文件或项目的状态,以便之后能够回溯到某个特定版本。
  • 游戏进度保存:在游戏中,玩家的进度(如等级、位置、装备等)可以存储为备忘录对象,并在玩家需要时从存档中恢复游戏。

3. 事务管理

在涉及复杂事务处理的系统中,备忘录模式可以用于事务回滚,即当事务中的某些操作失败时,能够恢复到之前的状态。

应用场景:

  • 数据库事务管理:在处理数据库事务时,如果某一步操作出错,可以回滚到事务开始时的状态,从而保证数据一致性。
  • 金融交易系统:在处理复杂的金融交易时,如果发生异常,能够回滚到交易前的状态,避免数据异常。

4. 需要避免暴露对象细节

在某些情况下,系统可能需要恢复对象的状态,但不希望暴露对象的内部实现细节。备忘录模式可以在不破坏对象封装的情况下,保存和恢复对象状态。

应用场景:

  • 封装复杂对象:例如,某个对象的内部状态比较复杂,外部系统需要在多个状态之间切换,但是不希望外部直接访问对象的内部状态。备忘录模式允许外部保存和恢复状态,而不需要了解对象的内部实现。

5. 定时或阶段性保存

当系统需要阶段性地保存对象的状态,以防系统崩溃或其他意外情况时,备忘录模式可以记录当前的状态,确保系统可以在异常结束后恢复到安全状态。

应用场景:

  • 自动备份系统:例如,某个系统在特定时间或操作后定时保存数据,并在崩溃后自动恢复。

6. 数据快照

当系统需要保存某一时刻的状态快照,以便后续能够对比或恢复时,备忘录模式可以记录状态快照。

应用场景:

  • 调试与监控:开发人员可以在系统运行的不同阶段记录状态快照,并在调试过程中进行恢复以定位问题。

7. 复杂状态管理

对于那些有复杂状态管理需求的系统,备忘录模式可以帮助解决状态的存储与恢复问题,确保状态管理的灵活性。

应用场景:

  • 用户设置的恢复:在软件应用中,用户可能会进行复杂的设置操作,通过备忘录模式,系统可以允许用户将配置恢复到之前的某个设置。

局限性

尽管备忘录模式适用于上述场景,但它在某些情况下可能不是最优选择,特别是当:

  • 状态数据庞大:如果对象的状态信息较大,存储多个备忘录对象可能会占用大量内存。
  • 状态变更频繁:在频繁保存状态的情况下,备忘录的维护成本较高,可能会引发性能问题。

总结

备忘录模式的优点在于它在保持对象封装性、实现撤销功能、简化状态管理、降低耦合度的同时,支持系统的状态历史保存和事务处理回滚。它特别适用于需要保存和恢复对象状态的应用场景。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Anthropic介绍Contextual Retrieval

人工智能模型要想在特定环境中发挥作用&#xff0c;往往需要获取背景知识。 例如&#xff0c;客户支持聊天机器人需要了解具体的业务&#xff0c;而法律分析机器人则需要了解大量的过往案例。 开发人员通常使用检索增强生成&#xff08;RAG&#xff09;来增强人工智能模型的知…

LEAN 赋型唯一性(Unique Typing)之 Church-Rosser 定理 (Church-Rosser Theorem)及 赋型唯一性的证明

有了并行K简化的概念及其属性&#xff0c;以及其在LEAN类型理论中的相关证明&#xff0c;就可以证明&#xff0c;在K简化下的Church-Rosser 定理。即&#xff1a; 其过程如下&#xff1a; 证明如下&#xff1a; 其中的 lemma 4.9 和 4.10 &#xff0c;及 4.8 是 这整个证明过程…

ImportError: /lib/x86 64-linux-gnu/libm.so.6:version GLIBc 2.29‘ not found

一、概述 在编译时出现一些问题&#xff0c;在网上搜索之后&#xff0c;对问题进行整理记录。 二、具体解决方法 &#xff08;一&#xff09;问题 如图所示&#xff0c;在编译过程中出现如下的问题。 &#xff08;二&#xff09;问题分析 通过在网络查询&#xff0c;在github…

后端-navicat查找语句(单表与多表)

表格字段设置如图 语句&#xff1a; 1.输出 1.输出name和age列 SELECT name,age from student 1.2.全部输出 select * from student 2.where子语句 1.运算符&#xff1a; 等于 >大于 >大于等于 <小于 <小于等于 ! <>不等于 select * from stude…

传统软件在定制化方面有哪些优势,SaaS 软件如何克服这一劣势?

一、传统软件在定制化优势 传统软件在定制化方面的优势主要体现在以下几个方面&#xff1a; 个性化需求满足&#xff1a;传统软件可以根据客户的特定需求进行个性化定制&#xff0c;提供定制化的解决方案&#xff0c;满足客户的业务流程和功能需求。灵活性和扩展性&#xff1a…

使用 Vue 3、Vite 和 TypeScript 的环境变量配置

使用 Vue 3、Vite 和 TypeScript 的环境变量配置 在开发现代前端应用时&#xff0c;环境变量是一个非常重要的概念。它可以帮助我们根据不同的环境&#xff08;开发、测试、生产&#xff09;配置不同的行为&#xff0c;比如 API 请求地址、调试选项等。在 Vue 3、Vite 和 Type…

一个.NET开发且功能强大的Windows远程控制系统

项目介绍 SiMayRemoteMonitorOS是一个基于Windows的远程控制系统&#xff0c;完全采用C#.NET开发&#xff0c;遵循AGPL-3.0开源协议。 核心功能 远程桌面&#xff1a;基于逐行扫描算法&#xff0c;提供流畅的远程桌面体验&#xff0c;支持多屏幕切换&#xff0c;以及全屏监控…

【C++】类和对象(下):再探构造函数、类型转换、static成员、友元、内部类、匿名对象、拷贝对象时编译器的优化

这篇博文是C中类和对象的最后一些知识&#xff0c;包括再探构造函数、类型转换、static成员、友元、内部类、匿名对象、拷贝对象时编译器的优化这些知识点。 1.再探构造函数 之前我们实现构造函数时&#xff0c;初始化成员变量主要是使用函数体内赋值&#xff0c;构造函数初始化…

neo4j:ubuntu环境下的安装与使用

一、neo4j安装 1. 下载安装包 进入网站&#xff1a;https://neo4j.com/deployment-center/#community 在上图中选择下载即可&#xff08;社区版免费&#xff09; 注意&#xff1a;neo4j的版本要和电脑安装的jdk版本对应&#xff0c;jdk版本使用java --version查看&#xff1a;…

计算机视觉的应用34-基于CV领域的人脸关键点特征智能提取的技术方法

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用34-基于CV领域的人脸关键点特征智能提取的技术方法。本文主要探讨计算机视觉领域中人脸关键点特征智能提取的技术方法。详细介绍了基于卷积神经网络模型进行人脸关键点提取的过程&#xff0c;包括使…

长列表加载性能优化

一、长列表优化概述 列表是应用开发中最常见的一类开发场景&#xff0c;它可以将杂乱的信息整理成有规律、易于理解和操作的形式&#xff0c;便于用户查找和获取所需要的信息。应用程序中常见的列表场景有新闻列表、购物车列表、各类排行榜等。随着信息数据的累积&#xff0c;特…

基于SpringBoot的漫画网设计与实现

博主介绍&#xff1a;专注于Java vue .net php phython 小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找不到哟 我的博客空间发布了1000毕设题目 方便大家学习使用 感兴趣的…

Java 每日一刊(第14期):抽象类和接口

“抽象是所有能力的精髓。” 前言 这里是分享 Java 相关内容的专刊&#xff0c;每日一更。 本期将为大家带来以下内容&#xff1a; 抽象类接口抽象类和接口的区别什么时候用抽象类&#xff0c;什么时候用接口抽象类可以实现接口接口中的常量其实是 public static final标记…

C语言图形编程:构建视觉效果与应用

引言 在计算机科学的领域中&#xff0c;C语言凭借其简洁、高效以及对底层硬件的强大控制能力&#xff0c;一直是系统级编程的首选语言之一。尽管近年来出现了许多高级语言&#xff0c;但C语言仍然在多个领域占据着重要地位&#xff0c;特别是在图形编程方面。本文将深入探讨如…

粒子向上持续瀑布动画效果(直接粘贴到记事本改html即可)

代码&#xff1a; 根据个人喜好修改即可 <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>宽粒子向上…

MOSFET是什么,终于有了一点点感知

目录 MOSFET是什么&#xff1f;FETMOS MOSFET和功率MOSFETMOSFET功率MOSFET MOSFET是什么&#xff1f; 英文是metal-oxide-semiconductor-field-effect-transistor&#xff0c;金属氧化物半导体场效应晶体管。 可以分开来看一下&#xff0c;MOS和FET FET 其中&#xff0c;FE…

图片类型转化---模拟某wps

文件上传功能的深入探讨 文件上传是Web应用程序中常见的功能&#xff0c;它允许用户将本地文件通过Web界面发送到服务器。在Flask中&#xff0c;这通常是通过处理表单数据来实现的。表单必须设置enctype为multipart/form-data&#xff0c;这样浏览器才能将文件作为多部分消息发…

Linux常用命令(部分学习待继续补充)

pwd print working directory 打印当前的工作目录 / 根目录 ls list 列出当前目录下的所有文件 ls / ls -h(human) ls -l(long) cd change directory 更改目录 cd … 回到上一级目录 ls list ls -l 会列出文件的详细信息 第一个字符是-表示普通文件 d表示是一个目录 rwx read …

keil 下载安装 保姆级教程

一.前言 最近被安排开发一个单片机的项目&#xff0c;回头想了一下&#xff0c;自己上次弄单片机的时候&#xff0c;还都是在大学期间&#xff0c;到现在也有三四年没有碰过了&#xff0c;大部分的知识点都忘了&#xff0c;所以又重新的把以前的笔记和资料&#xff0c;拿出来温…

NXP实战笔记(十六):NXP 32K3xx系列单片机有关OTA升级的思考

目录 1、概述 2、参考资料 3、思考点1&#xff1a;需不需要传统BootLoader&#xff1f; 3.1、无需传统BootLoader 3.2、有传统BootLoader 4、OTA升级之后是否立即实施切换 5、兼容编程会话 6、APP内部集成34、36、37服务 7、Flash放置问题 1、概述 NXP的S32K3系列单片机…