23种设计模式-备忘录(Memento)设计模式

news2025/3/31 22:13:12

备忘录设计模式

  • 🚩什么是备忘录设计模式?
  • 🚩备忘录设计模式的特点
  • 🚩备忘录设计模式的结构
  • 🚩备忘录设计模式的优缺点
  • 🚩备忘录设计模式的Java实现
  • 🚩代码总结
  • 🚩总结

🚩什么是备忘录设计模式?

备忘录设计模式(Memento Pattern) 是一种 行为型设计模式,用于在不破坏对象封装性的前提下,捕获对象的内部状态,并在未来的某个时间点恢复到该状态。该模式可以帮助我们实现 撤销(Undo) 操作,常用于文本编辑器、事务管理等场景。

使用场景

  • 需要 保存和恢复对象的状态,比如 撤销/重做 功能

  • 需要 防止外部对象直接访问对象的私有状态,保持封装性

  • 需要 在历史记录中存储对象的多个状态,支持回溯

🚩备忘录设计模式的特点

  • 封装性:对象的状态被存储在备忘录中,避免外部访问

  • 状态恢复:允许对象恢复到之前的状态,支持回溯操作

  • 简化历史记录管理:可以存储多个历史状态,支持撤销、重做等功能

  • 解耦设计:原发器(Originator)与管理者(Caretaker)解耦,原发器只负责创建和恢复状态,管理者负责存储

🚩备忘录设计模式的结构

备忘录模式主要包含以下部分:

  • Originator(原发器):负责创建备忘录(Memento)并存储当前状态,支持从备忘录恢复状态

  • Memento(备忘录):存储原发器的状态,并提供恢复该状态的方法

  • Caretaker(管理者):负责存储多个备忘录对象,可以提供回溯功能

🚩备忘录设计模式的优缺点

✅ 优点

  • 封装性好,外部对象无法直接访问对象的状态

  • 支持撤销和重做功能,适用于编辑器、事务管理等场景

  • 解耦原发器和管理者,增强了代码的可维护性

❌ 缺点

  • 内存消耗大,如果存储大量状态,可能会影响系统性能

  • 状态存储复杂,如果对象的状态较大,存储和恢复的成本较高

🚩备忘录设计模式的Java实现

代码地址:GitHub

  • 创建 Memento(备忘录) 类
/**
 * @author hanson
 * @description: 备忘录
 * @date 2025-03-25 22:57:26
 * @version: 1.0
 */
public class Memento {// 备忘录
    private String state;

    public Memento(String state) {
        this.state = state;
    }

    public String getState() {
        return state;
    }
}
  • 创建Originator(原发器)
/**
 * @author hanson
 * @description: 原发器
 * @date 2025-03-25 22:56:35
 * @version: 1.0
 */
public class Originator {// 原发器
    private String state;

    public void setState(String state) {
        this.state = state;
    }

    public String getState() {
        return state;
    }

    public Memento createMemento() {
        return new Memento(state);
    }

    public void setMemento(Memento memento) {
        state = memento.getState();
    }
}
  • 创建Caretaker(管理者)
/**
 * @author hanson
 * @description: 管理者
 * @date 2025-03-25 22:58:35
 * @version: 1.0
 */
public class Caretaker {// 管理者

    private List<Memento> mementoList = new ArrayList<>();

    public void addMemento(Memento state) {
        mementoList.add(state);
    }

    public Memento getMemento(int index) {
        // 判断参数是否合法
        if (index >= 1 && index <= mementoList.size()) {
            return mementoList.get(index - 1);
        }

        return null;
    }

    public void showMemento() {
        int cnt = 1;
        // for (遍历对象类型 对象名 : 遍历对象)
        for (Memento memento : mementoList) {
            System.out.println("第" + cnt + "次备份,状态为:" + memento.getState());

            cnt++;
        }
    }
}
  • 测试备忘录模式
/**
 * @author hanso
 * @description: 测试备忘录模式
 * @date 2025-03-25 23:00:25
 * @version: 1.0
 */
public class MementoPattern {
    public static void main(String[] args) {
        Caretaker caretaker = new Caretaker();
        Originator originator = new Originator();

        originator.setState("1024");
        Memento backup1 = originator.createMemento();
        caretaker.addMemento(backup1);

        originator.setState("2048");
        Memento backup2 = originator.createMemento();
        caretaker.addMemento(backup2);

        originator.setState("4096");
        Memento backup3 = originator.createMemento();
        caretaker.addMemento(backup3);

        System.out.println(originator.getState());

        caretaker.showMemento();

        Memento memento1 = caretaker.getMemento(2);
        originator.setMemento(memento1);

        System.out.println("根据第2次备份还原之后的状态为:" + originator.getState());
    }
}

📌 运行结果

在这里插入图片描述

🚩代码总结

  • Originator(原发器):负责创建备忘录,并存储和恢复状态

  • Memento(备忘录):存储状态,不对外暴露内部信息

  • Caretaker(管理者):管理多个备忘录对象,提供状态回溯功能

  • 支持多次状态存储与回溯,可用于撤销/重做功能

🚩总结

  • 备忘录设计模式 适用于 状态恢复撤销/重做 等场景

  • 解耦设计,原发器与管理者独立,避免外部访问对象状态

  • 支持历史记录管理,但需要注意 内存消耗问题

  • 广泛应用 于 文本编辑器事务管理游戏存档

✅ Java源码中的应用场景:

  1. 数据库事务管理:

    • 事务回滚(Rollback)

    • 事务日志(Transaction Log)

  2. Spring 事务管理(TransactionManager):

    • 通过事务日志(Transaction Log)来支持回滚

创作不易,不妨点赞、收藏、关注支持一下,各位的支持就是我创作的最大动力❤️

在这里插入图片描述

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

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

相关文章

2024年3月全国计算机等级考试真题(二级C语言)

&#x1f600; 第1题 下列叙述中正确的是 A. 矩阵是非线性结构 B. 数组是长度固定的线性表 C. 对线性表只能作插入与删除运算 D. 线性表中各元素的数据类型可以不同 题目解析&#xff1a; A. 矩阵是非线性结构 错误。矩阵通常是二维数组&#xff0c;属…

【MySQL】索引 事务

目录 一、索引 概念 作用 使用场景 使用 查看索引 创建索引 删除索引 背后的数据结构 二、事务 为什么使用事务 事务的概念 使用 开启事务 执行多条 SQL 语句 回滚或提交&#xff1a;rollback/commit; 事务的基本特性 原子性 一致性 持久性 隔离性 脏读 …

【江协科技STM32】软件SPI读写W25Q64芯片(学习笔记)

SPI通信协议及S为5Q64简介&#xff1a;【STM32】SPI通信协议&W25Q64Flash存储器芯片&#xff08;学习笔记&#xff09;-CSDN博客 STM32与W25Q64模块接线&#xff1a; SPI初始化&#xff1a; 片选SS、始终SCK、MOSI都是主机输出引脚&#xff0c;输出引脚配置为推挽输出&…

Git+Fork 入门介绍

git 分区理解 fork安装 从路径下去拿软件时&#xff0c;注意先拉到本地。经验来看&#xff0c;fork直接安装会出不可思议的问题。 fork操作 安装&#xff0c;注意设置好名字&#xff0c;如果之前安装的同学&#xff0c;名字没有写好&#xff0c;重新安装设置好名字。 clone操…

Windows系统安装Node.js和npm教程【成功】

0.引言——Node.js和npm介绍 项目描述Node.js基于Chrome V8引擎的JavaScript运行环境&#xff0c;使JavaScript可用于服务器端开发。采用单线程、非阻塞I/O及事件驱动架构&#xff0c;适用于构建Web服务器、实时应用和命令行工具等npmNode.js的包管理器与大型软件注册表。拥有…

Axure RP9.0 教程:左侧菜单列表导航 ( 点击父级菜单,子菜单自动收缩或展开)【响应式的菜单导航】

文章目录 引言I 实现步骤添加商品管理菜单组推拉效果引言 应用场景:PC端管理后台页面,左侧菜单列表导航。 思路: 用到了动态面板的两个交互效果来实现:隐藏/显示切换、展开/收起元件向下I 实现步骤 添加商品管理菜单组 在左侧画布区域添加一个菜单栏矩形框;再添加一个商…

科技赋能|ZGIS综合管网智能管理平台守护地下城市生命线

地下管网作为城市公共安全的重要组成部分&#xff0c;担负着城市的信息传递、能源输送、排涝减灾等重要任务&#xff0c;是维系城市正常运行、满足群众生产生活需要的重要基础设施&#xff0c;是城市各功能区有机连接和运转的维系&#xff0c;因此&#xff0c;也被称为城市“生…

如何保证LabVIEW软件开发的质量?

LabVIEW作为图形化编程工具&#xff0c;广泛应用于工业测控、自动化测试等领域。其开发模式灵活&#xff0c;但若缺乏规范&#xff0c;易导致代码可读性差、维护困难、性能低下等问题。保证LabVIEW开发质量需从代码规范、模块化设计、测试验证、版本管理、文档完善等多维度入手…

如何快速解决 Postman 报错?

介绍一些 Postman 常见的报错与处理方法&#xff0c;希望能够对大家有所帮助。 Postman 一直转圈打不开的问题 Postman 报错处理指南&#xff1a;常见报错与解决方法

C++ 多线程简要讲解

std::thread是 C11 标准库中用于多线程编程的核心类&#xff0c;提供线程的创建、管理和同步功能。下面我们一一讲解。 一.构造函数 官网的构造函数如下&#xff1a; 1.默认构造函数和线程创建 thread() noexcept; 作用&#xff1a;创建一个 std::thread 对象&#xff0c;但…

如何设计一个处理物联网设备数据流的后端系统。

一、系统架构设计 物联网设备数据流的后端系统通常包括以下几个主要组件: ①设备数据采集层:负责从物联网设备收集数据。 ②数据传输层:负责将设备数据传输到后端系统。 ③数据处理层:实时或批量处理传输到后的数据。 ④存储层:负责存储设备数据。 ⑤API层:提供外部…

深入理解 Spring Boot 应用的生命周期:从启动到关闭的全流程解析

引言 Spring Boot 是当今 Java 开发中最流行的框架之一&#xff0c;它以简化配置和快速开发著称。然而&#xff0c;要真正掌握 Spring Boot&#xff0c;理解其应用的生命周期是至关重要的。本文将深入探讨 Spring Boot 应用的生命周期&#xff0c;从启动到关闭的各个阶段&…

【算法笔记】图论基础(一):建图、存图、树和图的遍历、拓扑排序、最小生成树

目录 何为图论图的概念 图的一些基本概念有向图和无向图带权图连通图和非连通图对于无向图对于有向图 度对于无向图对于有向图一些结论 环自环、重边、简单图、完全图自环重边简单图 稀疏图和稠密图子图、生成子图同构 图的存储直接存边邻接矩阵存边邻接表存边链式前向星存边 图…

SpringMVC 请求与响应处理详解

引言 在 Java Web 开发中&#xff0c;SpringMVC 作为 Spring 框架的重要模块&#xff0c;提供了强大的请求和响应处理机制。本文将深入探讨 SpringMVC 中请求和响应的处理方式&#xff0c;结合实际案例&#xff0c;帮助开发者更好地理解和应用这些功能。 一、SpringMVC 请求处…

【python】requests 爬虫高效获取游戏皮肤图

1. 引言 在当今的数字时代&#xff0c;游戏已经成为许多人生活中不可或缺的一部分。而游戏中的皮肤&#xff0c;作为玩家个性化表达的重要方式&#xff0c;更是受到了广泛的关注和喜爱。然而&#xff0c;对于许多玩家来说&#xff0c;获取游戏皮肤往往需要花费大量的时间和精力…

(UI自动化测试web端)第二篇:元素定位的方法_css定位之ID选择器

看代码里的【find_element_by_css_selector( )】( )里的表达式怎么写&#xff1f; 文章介绍了第一种写法id选择器&#xff0c;其实XPath元素定位要比CSS好用&#xff0c;原因是CSS无法使用下标&#xff08;工作当中也是常用的xpath&#xff09;&#xff0c;但CSS定位速度比XPat…

23种设计模式-代理(Proxy)设计模式

代理设计模式 &#x1f6a9;什么是代理设计模式&#xff1f;&#x1f6a9;代理设计模式的特点&#x1f6a9;代理设计模式的结构&#x1f6a9;代理设计模式的优缺点&#x1f6a9;代理设计模式的Java实现&#x1f6a9;代码总结&#x1f6a9;总结 &#x1f6a9;什么是代理设计模式…

【react18】react项目使用mock模拟后台接口

前后端分离项目&#xff0c;后端还没有接口的时候&#xff0c;前端可以使用mockjs的技术实行假数据的模拟。这里使用的是mock的库msw实现这个业务. MSW msw是mock的工具&#xff0c;官网地址是在这里 使用步骤 1.安装msw npm install mswlatest --save-dev2.新建存放mock接…

Windows下VSCode的安装

前言 VSCode的安装看起来平平无奇&#xff0c;但也不是轻轻松松的。笔者将最新的Windows下安装VSCode&#xff0c;以及运行最简单的C程序的过程记录下来&#xff0c;供后续的自己和大家参考。 一、官网下载安装包 Visual Studio Code - Code Editing. Redefined 二、安装 直接…

django入门教程之templates和static资源【五】

使用app01子应用举例说明模板的使用。templates官方文档。 templates完整流程认知 第一步&#xff0c;在settings.py中注册app01子应用。 第二步&#xff0c;在app01目录下&#xff0c;新建templates和static目录&#xff0c;用于存放模板文件和资源文件。目录结构如下&#…