【设计模式深度剖析】【8】【行为型】【备忘录模式】| 以后悔药为例加深理解

👈️上一篇:观察者模式

设计模式-专栏👈️

---

文章目录

  • 备忘录模式
  • 定义
    • 英文原话
    • 直译
    • 如何理解呢?
  • 3个角色
    • 1. Memento(备忘录)
    • 2. Originator(原发器)
    • 3. Caretaker(负责人)
    • 类图
    • 代码示例
  • 备忘录模式的应用
    • 备忘录模式的优点
    • 备忘录模式的缺点
    • 备忘录模式的使用场景

备忘录模式

备忘录模式(Memento Pattern)又称为快照(Snapshot)模式或Token模式。

备忘录模式就像我们在生活中使用的“后悔药”。有时候,我们可能会做出一些决定或操作,但事后可能会后悔,希望回到之前的状态。备忘录模式就是这样一种“后悔药”,它能够帮助我们在需要的时候,返回到之前的状态。比如,在写文档时,如果我们不小心删除了一个重要的段落,使用备忘录模式,我们就可以轻松地恢复到删除之前的状态。但是,这种“后悔药”也有副作用,那就是它可能会占用一些资源,就像我们需要空间来保存这些后悔的机会一样。

定义

英文原话

Without violating encapsulation,capture and externalizean object’s internal state so that the object can be restored to this state later.

直译

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

如何理解呢?

有时有必要记录一个对象的内部状态。

为了允许用户取消不确定的操作或从错误中恢复过来,需要实现检查点和取消机制,而要实现这些机制,你必须事先将状态信息保存在某处,这样才能将对象恢复到他们先前的状态。

但是对象通常封装了其部分或所有的状态信息,使得其状态不能被其他对象访问,也就不可能在该对象之外保存其状态。

而暴露其内部状态又将违反封装的原则,可能有损应用的可靠性和可扩展性。

我们可以用备忘录(Memento)模式解决这一问题。

一个备忘录(memento)是一个对象,他存储另一个对象(原发器originator)在某个瞬间的内部状态,而后者称为备忘录的原发器originator)。

当需要设置原发器的检查点时,备份机制向原发器请求一个备忘录。

原发器用描述当前状态的信息初始化备忘录

只有原发器(originator)可以向备忘录中存取信息,备忘录对其他的对象不可见。

适用于必须保存一个对象在某一时刻的(部分)状态(以便以后有需要可以恢复回此状态)且如果用接口让其他对象直接得到这些状态,将会暴露对象实现细节并破坏对象的封装性。在这样的场景下使用备忘录(Memento)模式。

3个角色

1. Memento(备忘录)

负责存储Originator对象的内部状态,并可以防止Originator以外的其他对象访问备忘录。

备忘录有两个接口:Caretaker只能看到备忘录的窄接口,他只能将备忘录传递给其他对象;而Originator却可看到备忘录的宽接口,允许它访问返回到先前状态所需要的所有数据。

2. Originator(原发器)

originator创建一个备忘录,用以记录当前时刻它的内部状态。

使用备忘录回复内部状态。

只有创建备忘录的原发器会对他的状态状态进行赋值和检索。

3. Caretaker(负责人)

负责保存好备忘录。

不能对备忘录的内容进行操作或检查。

负责保存与提供备忘录对象,但是不能对备忘录的内容进行访问或者操作。

类图

在这里插入图片描述

代码示例

package com.polaris.designpattern.list3.behavioral.pattern08.memento.classicdemo;

// 备忘录接口
interface Memento {
    // 可能包含一些用于获取状态的方法  
    String getState();
}

// 发起人(Originator)  
class Originator {
    private String state;

    // 创建一个备忘录并保存当前状态  
    public Memento createMemento() {
        return new MementoImpl(state);
    }

    // 恢复发起人状态  
    public void restoreMemento(Memento memento) {
        this.state = ((MementoImpl) memento).getState();
    }

    // 设置发起人状态  
    public void setState(String state) {
        this.state = state;
    }

    // 获取发起人状态  
    public String getState() {
        return state;
    }

    // 备忘录实现类,仅供发起人使用  
    private static class MementoImpl implements Memento {
        private String state;

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

        public String getState() {
            return state;
        }
    }
}

// 管理者(Caretaker)  
class Caretaker {
    private Memento memento;

    // 保存备忘录  
    public void setMemento(Memento memento) {
        this.memento = memento;
    }

    // 获取备忘录  
    public Memento getMemento() {
        return memento;
    }
}

// 使用示例  
public class MementoPatternDemo {
    public static void main(String[] args) {
        Originator originator = new Originator();
        Caretaker caretaker = new Caretaker();

        originator.setState("State #1");
        System.out.println("Current State: " + originator.getState());

        // 保存当前状态  
        caretaker.setMemento(originator.createMemento());

        originator.setState("State #2");
        System.out.println("Current State: " + originator.getState());

        // 恢复之前的状态  
        originator.restoreMemento(caretaker.getMemento());
        System.out.println("Restored State: " + originator.getState());
    }
}

/* Output:
Current State: State #1
Current State: State #2
Restored State: State #1
*///~

在这个例子中,Originator类维护了一个内部状态state,并提供了创建备忘录(createMemento)和恢复状态(restoreMemento)的方法。备忘录的实际实现是MementoImpl类,但它被声明为Originator的私有内部类,因此外部类(如Caretaker)不能直接访问它。Caretaker类负责管理备忘录对象。在MemontoPatternDemo类中,我们展示了如何使用这些类来保存和恢复Originator的状态。

备忘录模式的应用

备忘录模式,又称之为快照模式(Snapshot Pattern),是一种软件设计模式,主要用于保存和恢复对象的内部状态。以下是其主要应用:

  1. 撤销和恢复功能:在Word、PhotoShop等软件中,用户可以撤销之前的操作,或恢复到某个历史状态。备忘录模式能够记录用户的每一步操作,从而实现这一功能。
  2. 电子书的阅读进度:用户在阅读电子书时,可以随时保存阅读进度,下次打开时可以从上次的阅读进度继续阅读。
  3. 软件开发中的版本控制:记录每个版本的代码快照,方便进行版本控制和回溯。
  4. 事务管理:在数据库事务处理中,如果一系列操作不能全部完成,就需要回滚操作,将数据恢复到操作之前的状态。备忘录模式可以记录一系列操作的快照,当需要回滚时,可以恢复到备忘录状态。

备忘录模式的优点

  1. 提供恢复机制:为用户提供一种可以恢复状态的机制,允许在必要时将对象恢复到之前的状态。
  2. 实现内部状态的封装:除了创建它的发起人之外,其他对象都不能够访问这些状态信息,这有助于保持封装的边界。
  3. 简化发起人类:发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则。

备忘录模式的缺点

  1. 资源消耗大:如果要保存的内部状态信息过多或者特别频繁,将会占用比较大的内存资源。
  2. 难以预测存储需求:当负责人角色将一个备忘录存储起来的时候,可能无法预测这个状态会占用多大的存储空间,从而无法提醒用户一个操作是否很昂贵。

备忘录模式的使用场景

备忘录模式适用于需要保存/恢复数据的相关业务场景,如:

  1. 撤销操作:在文本编辑器、图形编辑器等工具中,用户可能需要撤销之前的操作。
  2. 游戏存档:在游戏中,玩家可能需要存档以便在之后恢复游戏进度。
  3. 数据库事务管理:在数据库事务处理中,如果一系列操作不能全部完成,就需要回滚操作,将数据恢复到操作之前的状态。

---

👈️上一篇:观察者模式

设计模式-专栏👈️

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

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

相关文章

每日一题——Python实现PAT乙级1028 人口普查 Keyboard(举一反三+思想解读+逐步优化)六千字好文

一个认为一切根源都是“自己不够强”的INTJ 个人主页:用哲学编程-CSDN博客专栏:每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 题目链接​编辑我的写法 专业点评 时间复杂度分析 空间复杂度分析 总结 我要更强…

Star-CCM+自动网格执行方法与设置技巧

在Star中进行一个仿真项目时,有时会创建多个自动网格。网格创建结束后需要执行。在Star中,网格执行可以分为三种。分别是:单独执行操作;多个执行操作;全部执行操作。接下来将三种执行操作的方法与步骤进行介绍。 其次,如果不习惯用自定义控制网格,有时在一个项目中就会…

认识一些分布函数-Gumbel分布

1. Gumbel分布 Gumbel分布(也称为古贝尔型)是一种常用的非对称极值分布( Extreme Value Distribution,EVD),用于建模极大值和极小值,也就是所谓的EVD Type I分布。例如,EVD Type I 被用来预测地震、洪水和其他自然灾害,以及在风险管理中建模操作风险和那些在一定年龄…

关于阿里云效流水线自动部署项目教程

1、登录阿里云效:阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台 2、点击左侧流水线: 3、在流水线界面,新建流水线 4、我的是php代码,因此选择php模版 5、创建之后添加流程线源,如下图 6、选择相应的源头。比…

eclipse中报出Invaild project path

一、问题: 二、提示分析: 资源路径位置类型无效的项目路径:找到重复的路径条目 项目路径中有一个名为"/eclipse_rtt_demo"的条目被多次定义,这在Eclipse的构建路径设置中是不允许的。这个重复的条目既被标记为系统包含…

Studio One软件最新版下载及详细安装教程

Studio One 6是一款功能丰富、专业级的音乐制作软件,它具备灵活的工作流程和高效的团队协作能力,能帮助用户实现高质量的音乐创作和制作。 智能模板更快的启动,全新的智能模板为你手头的任务提供了必要的工具集,包括基本录制、混音…

【个人云盘连接助手】解决多个用户账号无法同时映射到本地磁盘问题

问题 家里买了个联想个人云盘,但是使用SAMBA映射到windows本地磁盘时,每次只能连接到一个账户上,于是想着写个小工具,方便切换多个用户账户,自动映射到本地磁盘 开发简介 开发语言:python 主要实现功能&…

训练营第三十六天| 337.打家劫舍 III121. 买卖股票的最佳时机

337.打家劫舍 III 力扣题目链接(opens new window) 在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为“根”。 除了“根”之外,每栋房子有且只有一个“父“房子与之相连。一番侦察…

工业屏:千万不要以为电脑显示啥样,工业屏就啥样,注意色差。

重要的事情说三遍:一定要放到实际场景下调色,定要放到实际场景下调色,定要放到实际场景下调色。 工业控制屏的色域通常比普通电脑显示器要小。工业控制屏主要用于工业环境中,需要满足特定行业的需求和标准。由于工业控制屏的设计…

深度剖析淘宝扭蛋机源码:打造趣味性电商活动的秘诀

在当今电商市场中,如何吸引用户的注意力、提升用户的参与度成为了各大电商平台竞相追求的目标。淘宝扭蛋机作为一种新型的电商活动形式,以其趣味性和互动性深受用户喜爱。本文将深度剖析淘宝扭蛋机源码,探讨其如何打造趣味性与互动性并存的电…

可视化图表走起来(1):桑基图,一目了然数据流向。

从事可视化设计,什么时候选用什么样的图表非常重要,今天来介绍一下桑基图的定义、场景、数据项等等,贝格前端工场愿意与各位老铁一道成长。 一、桑基图的定义 桑基图(Sankey diagram)是一种特殊类型的可视化图表&…

深入解析 Spring Cloud Sentinel:分布式系统流量控制与熔断降级的全面指南

📢📢📢 深入解析 Spring Cloud Sentinel:分布式系统流量控制与熔断降级的全面指南 Spring Cloud Sentinel 是阿里巴巴开源的一款强大的分布式系统流量防卫组件,专为微服务架构设计,提供流量控制、熔断降级…

【Spring6】13-19章 JdbcTemplate+代理模式+AOP+Spring事务+Spring集成MyBatis

十三、JdbcTemplate JdbcTemplate是Spring提供的一个JDBC模板类,是对JDBC的封装,简化JDBC代码。 当然,你也可以不用,可以让Spring集成其它的ORM框架,例如:MyBatis、Hibernate等。 接下来我们简单来学习一下…

【LVGL】Guider 界面分析

文章目录 前言架构创建 UI切换界面空间释放分析创建页面空间变化 前言 分析Gui Guider-1.7.2-GA 生成的 LVGL 界面切换,资源管理等处理 架构 所有控件存放于同一个结构体 lv_ui 内,每个页面都至少包含 screen_xxx 和 screen_xxx_del 两个成员 typede…

Cask ‘oraclexxx‘ is unavailable: No Cask with this name exists.

brew search oracle-jdk或brew search --cask oracle-jdk 原因:Homebrew官方仓库不再维护多个旧版本的OracleJDK 不推荐使用Homebrew环境安装JDK //指定版本安装 brew install --cask temurin17 //设置 JAVA_HOME 环境变量 //找到安装的JDK 版本的路径 /usr/lib…

大数据可视化电子沙盘:前端技术的全新演绎

随着大数据时代的到来,数据可视化成为了一个重要的技术趋势。数据可视化不仅可以让复杂的数据变得更加直观易懂,还能帮助我们更好地分析和理解数据。在本文中,我们将深入探讨一种基于HTML/CSS/Echarts等技术的大数据可视化电子沙盘&#xff0…

MAC系统下安装VUE

下载node.js 点击链接 选择图片中的稳定版本 安装node.js 打开终端,输入 node -v 和 npm -v 显示如上信息表示安装成功 安装vue脚手架🔧 sudo npm install -g vue/cli查看vue版本 vue -V6. 启动项目 1 采用 图形页面方式 控制台输入&#xff…

前端菜鸡流水账日记 -- Pagination分页

哈喽哇大家,老规矩,见面先问好,今天是端午节假期后的第一天上班,大家假期开心吗,哈哈哈哈,我还是蛮开心的... 今天这篇笔记要分享得主要是一个分页器,但是不一样得地方是因为,首先是…

5G和LED显示屏的关系

显示屏和5G看似没有直接关系,但实际上,两者之间的关联非常密切。北京的LED显示屏行业依赖于网络技术的进步,才有了今天的发展。随着5G时代的到来,万物互联的全面开启将为LED显示屏行业带来新的机遇和挑战。本文将详细探讨5G与LED显…

项目采购管理

目录 1.概述 2.三个子过程 2.1.规划采购管理 2.2.实施采购 2.3.控制采购 2.4.归属过程组 3.应用场景 3.1.十个应用场景 3.2.软件开发项目 3.2.1. 需求识别和分析 3.2.2. 制定采购计划 3.2.3. 发布采购请求 3.2.4. 供应商评估与选择 3.2.5. 合同签订 3.2.6. 采购…