Java特性之设计模式【备忘录模式】

一、备忘录模式

概述

备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象,备忘录模式属于行为型模式

备忘录模式允许在不破坏封装性的前提下,捕获和恢复对象的内部状态

主要解决

允许捕获并保存一个对象的内部状态,以便在将来可以恢复到该状态,实现撤销和回滚操作

何时使用

  • 需要实现对象状态的撤销和恢复功能。当需要在对象中实现撤销操作或者恢复到先前状态的功能时,备忘录模式是一种有效的设计模式。它可以让对象保存其内部状态的快照,并在需要时进行恢复,从而实现撤销和恢复的功能

优缺点

优点:

  • 提供状态恢复机制:允许用户方便地回到历史状态
  • 封装状态信息:用户不需要关心状态的保存细节

缺点:

  • 资源消耗:如果对象的状态复杂,保存状态可能会占用较多资源

1. 各个角色介绍

1.1 备忘录(Memento)

  • 负责存储原发器对象的内部状态。备忘录可以保持原发器的状态的一部分或全部信息

1.2 原发器(Originator)

  • 创建一个备忘录对象,并且可以使用备忘录对象恢复自身的内部状态。原发器通常会在需要保存状态的时候创建备忘录对象,并在需要恢复状态的时候使用备忘录对象

1.3 负责人(Caretaker)

  • 负责保存备忘录对象,但是不对备忘录对象进行操作或检查。负责人只能将备忘录传递给其他对象

2. UML图

​ 备忘录模式使用三个类 MementoOriginatorCareTaker。Memento 包含了要被恢复的对象的状态。Originator 创建并在 Memento 对象中存储状态。Caretaker 对象负责从 Memento 中恢复对象的状态

在这里插入图片描述

3. 具体例子和代码

角色分配

  • Memento:备忘录

  • Originator:原发器

  • Caretaker:负责人

3.1 备忘录实体

  • Memento
package com.vinjcent.prototype.memento;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * @author vinjcent
 * @description 备忘录
 * @since 2024/5/16 20:11
 */
@Data
public class Memento {

    @ApiModelProperty(value = "状态")
    private String state;

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

}

3.2 原发器实体

  • Originator
package com.vinjcent.prototype.memento;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * @author vinjcent
 * @description 原发器
 * @since 2024/5/16 20:16
 */
@Data
public class Originator {

    @ApiModelProperty(value = "状态")
    private String state;

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

    public void getStateFromMemento(Memento memento) {
        state = memento.getState();
    }

}

3.3 负责人

  • CareTaker
package com.vinjcent.prototype.memento;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;

/**
 * @author vinjcent
 * @description 负责人
 * @since 2024/5/16 20:23
 */
@Data
public class CareTaker {

    @ApiModelProperty(value = "备忘录列表")
    private List<Memento> mementoList = new ArrayList<Memento>();

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

    public Memento get(int index) {
        return mementoList.get(index);
    }

}

3.4 测试主函数

package com.vinjcent.prototype.memento;

/**
 * @author vinjcent
 * @description 备忘录模式
 * @since 2024/5/16 20:24
 */
public class Main {

    public static void main(String[] args) {

        // 原发器
        Originator originator = new Originator();

        // 负责人
        CareTaker careTaker = new CareTaker();
        originator.setState("State #1");
        originator.setState("State #2");

        // 让负责人记录当前备忘录的状态
        careTaker.add(originator.saveStateToMemento());
        originator.setState("State #3");

        // 让负责人记录当前备忘录的状态
        careTaker.add(originator.saveStateToMemento());
        originator.setState("State #4");

        System.out.println("Current State: " + originator.getState());
        originator.getStateFromMemento(careTaker.get(0));
        System.out.println("First saved State: " + originator.getState());
        originator.getStateFromMemento(careTaker.get(1));
        System.out.println("Second saved State: " + originator.getState());

    }

}

  • 测试结果
    在这里插入图片描述

4. 使用场景

  • 当需要提供一种撤销机制,允许用户回退到之前的状态时

在这里插入图片描述

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

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

相关文章

Python爬虫实战(实战篇)—17获取【CSDN某一专栏】数据转为Markdown列表放入文章中

文章目录 专栏导读背景结果预览1、页面分析2、通过返回数据发现适合利用lxmlxpath3、进行Markdown语言拼接总结 专栏导读 在这里插入图片描述 &#x1f525;&#x1f525;本文已收录于《Python基础篇爬虫》 &#x1f251;&#x1f251;本专栏专门针对于有爬虫基础准备的一套基…

【Linux】22. 线程控制

Linux线程控制 POSIX线程库 与线程有关的函数构成了一个完整的系列&#xff0c;绝大多数函数的名字都是以“pthread_”打头的 要使用这些函数库&#xff0c;要通过引入头文<pthread.h> 链接这些线程函数库时要使用编译器命令的“-lpthread”选项 线程创建 pthread_cr…

AI办公自动化:kimi批量新建文件夹

工作任务&#xff1a;批量新建多个文件夹&#xff0c;每个文件夹中的年份不一样 在kimi中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;要完成一个编写关于录制电脑上的键盘和鼠标操作的Python脚本的任务&#xff0c;具体步骤如下&#xff1a; 打开文件夹&…

二叉树习题精讲-相同的树

相同的树 100. 相同的树 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/same-tree/description/ /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/ bool i…

夏日防晒笔记

1 防晒霜 使用方法&#xff1a;使用前上下摇晃瓶身4至5次&#xff0c;在距离肌肤10至15cm处均匀喷上。如在面部使用&#xff0c;请先喷在掌心再均匀涂抹于面部。排汗量较多时或擦拭肌肤后&#xff0c;请重复涂抹以确保防晒效果。卸除时使用普通洁肤产品洗净即可。

通过date命令给日志文件添加日期

一、背景 服务的日志没有使用日志工具&#xff0c;每次重启后生成新日志文件名称相同&#xff0c;新日志将会把旧日志文件冲掉&#xff0c;旧日志无法保留。 为避免因旧日志丢失导致无法定位问题&#xff0c;所以需要保证每次生成的日志文件名称不同。 二、解决 在启动时&am…

cs61B-sp21 | lab6

cs61B-sp21 | lab6 TODO 1 在 CapersRepository.java 中 static final File CAPERS_FOLDER null; // TODO Hint: look at the join // function in Utils在 Utils.java 我们找到 join 函数&#xff0c;第一个 join 的作用是将 first 和 others 连接起来形成一个路径…

【ArcGISPro】3.1.5下载和安装教程

下载教程 arcgis下载地址&#xff1a;Трекер (rutracker.net) 点击磁力链下载弹出对应的软件进行下载 ArcGISPro3.1新特性 ArcGIS Pro 3.1是ArcGIS Pro的最新版本&#xff0c;它引入了一些新的特性和功能&#xff0c;以提高用户的工作效率和数据分析能力。以下是ArcGIS…

c#对操作系统的时间无法更新?

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

I.MX6ULL主频和时钟配置实验

系列文章目录 I.MX6ULL主频和时钟配置实验 I.MX6ULL主频和时钟配置实验 系列文章目录一、前言二、I.MX6U 时钟系统详解三、硬件原理四、 7 路 PLL 时钟源五、时钟树简介六、内核时钟设置七、PFD 时钟设置八、AHB、IPG 和 PERCLK 根时钟设置九、实验程序编写十、编译下载10.1编写…

线程池的实现

线程池是一种池式组件&#xff0c;通过创建和维护一定数量的线程&#xff0c;实现这些线程的重复使用&#xff0c;避免了频繁创建和销毁线程的开销&#xff0c;从而提升了性能 线程池的作用&#xff1a; 1.复用线程资源&#xff1b; 2.减少线程创建和销毁的开销&#xff1b; …

LBank研究院: DePIN赛道解析|加密精神与Jevons悖论的第三世界

作者&#xff1a;Eva&#xff0c;LBank研究员 *本人谨代表作者观点&#xff0c;不构成任何交易建议。 *本文内容为原创&#xff0c;版权为LBank所有&#xff0c;如需转载请注明作者和出处&#xff0c;否则将追究法律责任。 TLDR: DePIN是对传统老牌硬件的洗牌挑战&#xff…

excel 点击单元格的内容 跳转到其他sheet设置

如图点击1处跳转到2 按照如下图步骤操作即可

js setTimeout、setInterval、promise、async await执行顺序梳理

基础知识 async: 关键字用于标记一个函数为异步函数&#xff0c;该函数中有一个或多个promise对象&#xff0c;需要等待执行完成后才会继续执行。 await:关键字&#xff0c;用于等待一个promise对象执行完&#xff0c;并返回其中的值&#xff0c;只能在async函数内部使用。可…

【PB案例学习笔记】-11动画显示窗口

写在前面 这是PB案例学习笔记系列文章的第11篇&#xff0c;该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习&#xff0c;提高编程技巧&#xff0c;以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码&#xff0c;小凡都上传到了gite…

调用萨姆索诺夫函数:深入探索函数的参数与返回值

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、萨姆索诺夫函数的引入与调用 二、如何获取函数的返回值 三、无参数与无返回值的函数调…

基于魔搭开源推理引擎 DashInfer实现CPU服务器大模型推理--理论篇

前言 在人工智能技术飞速发展的今天&#xff0c;如何高效地在CPU上运行大规模的预训练语言模型&#xff08;LLM&#xff09;成为了加速生成式AI应用广泛落地的核心问题。阿里巴巴达摩院模型开源社区ModelScope近期推出了一款名为DashInfer的推理引擎&#xff0c;旨在解决这一挑…

语音控制系统的安全挑战与防御策略(上)

语音控制系统&#xff08;VCS&#xff09;提供了便捷的用户界面&#xff0c;涉及智能家居、自动驾驶汽车、智能客服等众多应用场景&#xff0c;已成为现代智能设备不可或缺的一部分。其市场规模预计到2023年达到70亿美元&#xff0c;这种扩张带来了重大的安全挑战&#xff0c;如…

STM32简易音乐播放器(HAL库)

一、设计描述 本设计以STM32MP157A单片机为核心控制器&#xff0c;加上其他的模块一起组成基于单片机的音乐盒的整个系统&#xff0c;通过不同频率的PWM使蜂鸣器播放音乐&#xff0c;通过按键中断实现歌曲切换&#xff0c;音量调节&#xff0c;定时器中断实现播放速度调节&…