备忘录模式

简介: 备忘录模式

一、什么是备忘录模式

备忘录模式又称快照模式,是一种行为型设计模式。它可以在不破坏封装性的前提下捕获一个对象的内部状态,并在对象之外保存这个状态,以便在需要的时候恢复到原先保存的状态

二、角色组成

  • 源发器(Originator):需要保存和恢复状态的对象。它创建一个备忘录对象,用于存储当前对象的状态,也可以使用备忘录对象恢复自身的状态。
  • 备忘录(Memento):存储源发器对象的状态。备忘录对象可以包括一个或多个状态属性,源发器可以根据需要保存和恢复状态。
  • 管理者(Caretaker):负责保存备忘录对象,但不能修改备忘录对象的内容。它可以存储多个备忘录对象,并决定何时将备忘录恢复给源发器。

三、优缺点

优点:

  • 状态保存与恢复:备忘录模式可以帮助我们保存对象的状态,并在需要时恢复到之前的状态。这在某些情况下非常有用,比如撤销操作或者程序崩溃后的恢复。
  • 封装性和隔离性:可以确保对象的状态保存在备忘录对象中,而不会暴露给其他对象。这为对象的封装性和隔离性提供了保护,使得对象的状态变化对其他对象是透明的。

缺点:

  • 内存占用:可能引起较大的内存占用,特别是当对象的状态较多且状态改变频繁时。每个备忘录对象都需要保存一份完整的状态,如果状态较多或者备忘录对象较多,可能会消耗大量内存。
  • 性能开销:备忘录模式涉及到创建、存储和恢复状态的操作,这些操作可能引起一定的性能开销。特别是在状态较大或者对象较复杂的情况下,备忘录模式的性能可能会受到影响。

四、应用场景

浏览器的回退:当我们点击回退箭头时,浏览器会回退到上一个被浏览的网站,以显示之前访问的页面。

文本编辑器的撤销:如果误删了一些内容或者想恢复之前的修改,可以进行撤销操作。

数据库事务管理:当执行数据库操作时,我们可以将当前数据库的状态保存到备忘录对象中,在回滚操作或者发生错误时,可以使用备忘录对象恢复到之前的数据库状态。

五、代码实现

下面以文本编辑器为例,解释一下备忘录模式。

用户可以在编辑器中输入文本,并允许回退到之前的编辑状态。其中Editor类代表文本编辑器**(源发器),它具有保存和恢复文本内容的功能。EditorMemento类表示备忘录对象**,用于保存Editor的状态。History类作为管理者,负责保存和管理备忘录对象。

5.0 UML类图

5.1 EditorMemento——备忘录(Memento)
/**
 * @author Created by njy on 2023/7/1
 * 1.备忘录(Memento):备忘录,保存编辑器的状态
 * 定义:存储源发器对象的状态。备忘录对象可以包括一个或多个状态属性,源发器可以根据需要保存和恢复状态。
 */
public class EditorMemento {
    //文本内容 (可以是属性、也可以是对象)
    private  String content;
    public EditorMemento(String content) {
        this.content = content;
    }
    public String getContent() {
        return content;
    }
}
5.2 Editor——源发器(Originator)
/**
 * @author Created by njy on 2023/7/1
 * 2.源发器(Originator):文本编辑器
 * 定义:需要保存和恢复状态的对象。它创建一个备忘录对象,用于存储当前对象的状态,也可以使用备忘录对象恢复自身的状态。
 */
public class Editor {
    //内容(可以是属性、也可以是对象)
    private String content;
    public void setContent(String content) {
        this.content = content;
    }
    public String getContent() {
        return content;
    }
    // 创建备忘录对象,保存当前状态
    public EditorMemento createMemento() {
        return new EditorMemento(content);
    }
    // 恢复备忘录对象保存的状态
    public void restoreMemento(EditorMemento memento) {
        content = memento.getContent();
    }
}
5.3 History——管理者(Caretaker)
/**
 * @author Created by njy on 2023/7/2
 * 3.管理者(Caretaker):历史记录
 * 定义:负责保存备忘录对象,但不能修改备忘录对象的内容。它可以存储多个备忘录对象,并决定何时将备忘录恢复给源发器。
 */
public class History {
    //备忘录可以保存多个状态
    private final List<EditorMemento> mementos = new ArrayList<>();
    // 保存备忘录对象的状态
    public void push(EditorMemento memento) {
        mementos.add(memento);
    }
    // 弹出(移除)最近保存的备忘录对象,并返回它
    public EditorMemento pop() {
        int lastIndex = mementos.size() - 1;
        EditorMemento lastMemento = mementos.get(lastIndex);
        mementos.remove(lastIndex);
        return lastMemento;
    }
}
5.4 testMemento
/**
 * @author Created by njy on 2023/7/2
 * 备忘录模式测试类
 */
@SpringBootTest
public class TestMemento {
    @Test
    void testMemento(){
        //创建文本编辑器(源发器)
        Editor editor = new Editor();
        //创建管理者
        History history = new History();
        // 编辑文本并保存状态
        editor.setContent("Hello");
        history.push(editor.createMemento());
        // 编辑更多文本并再次保存状态
        editor.setContent("Hello, Java!");
        history.push(editor.createMemento());
        editor.setContent("Hello,world!");
        System.out.println("当前内容: " + editor.getContent());
        // 恢复之前的状态
        editor.restoreMemento(history.pop());
        System.out.println("恢复后上一次内容: " + editor.getContent());
        editor.restoreMemento(history.pop());
        System.out.println("恢复后上二次内容: " + editor.getContent());
    }
}

六、总结

备忘录模式提供了一种灵活的机制来保存和恢复对象的状态,对于需要撤销、恢复或者状态管理的场景非常有用。然而,它也可能引起较大的内存占用和一定的性能开销,需要在使用之前慎重考虑。以下场景可以作为参考:

  • 撤销和恢复功能:可以通过保存对象的历史状态来实现撤销和恢复功能,比如文本编辑器、绘图应用程序或任务管理器。
  • 版本控制:如果你的应用程序需要跟踪对象状态的历史记录,并支持版本控制功能,备忘录模式可以帮助实现这种需求。例如,可以使用备忘录模式来实现文档的版本控制。
  • 多阶段事务:备忘录模式可以用于实现多阶段事务的状态管理。在一个事务中,可能需要保存中间状态,以便在需要时回滚到之前的状态。

END:更多设计模式的介绍,推荐移步至👉 23种设计模式学习导航(Java完整版)👈

本文转自 https://blog.csdn.net/weixin_45433817/article/details/131501970?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170347346416800188578503%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=170347346416800188578503&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-131501970-null-null.142v96pc_search_result_base9&utm_term=%E5%A4%87%E5%BF%98%E5%BD%95%E6%A8%A1%E5%BC%8F&spm=1018.2226.3001.4187,如有侵权,请联系删除。

相关文章
|
前端开发 UED
你需要知道的 CSS 技巧:图片篇2 你的图片裂开了怎么办?
你需要知道的 CSS 技巧:图片篇2 你的图片裂开了怎么办?
1096 0
|
测试技术 开发者 Python
自动化测试之美:从零构建你的软件质量防线
【10月更文挑战第34天】在数字化时代的浪潮中,软件成为我们生活和工作不可或缺的一部分。然而,随着软件复杂性的增加,如何保证其质量和稳定性成为开发者面临的一大挑战。自动化测试,作为现代软件开发过程中的关键实践,不仅提高了测试效率,还确保了软件产品的质量。本文将深入浅出地介绍自动化测试的概念、重要性以及实施步骤,带领读者从零基础开始,一步步构建起属于自己的软件质量防线。通过具体实例,我们将探索如何有效地设计和执行自动化测试脚本,最终实现软件开发流程的优化和产品质量的提升。无论你是软件开发新手,还是希望提高项目质量的资深开发者,这篇文章都将为你提供宝贵的指导和启示。
|
机器学习/深度学习 数据挖掘 数据处理
alteryx哪里开发的,如何收费
【6月更文挑战第23天】alteryx哪里开发的,如何收费
315 5
|
8月前
|
API
掌握 HTTP 请求的艺术:理解 cURL GET 语法
掌握 cURL GET 请求的语法和使用方法是 Web 开发和测试中的基本技能。通过灵活运用 cURL 提供的各种选项,可以高效地与 API 进行交互、调试网络请求,并自动化日常任务。希望本文能帮助读者更好地理解和使用 cURL,提高工作效率和代码质量。
548 7
|
机器学习/深度学习 人工智能 弹性计算
什么是阿里云GPU云服务器?GPU服务器优势、使用和租赁费用整理
阿里云GPU云服务器提供强大的GPU算力,适用于深度学习、科学计算、图形可视化和视频处理等多种场景。作为亚太领先的云服务提供商,阿里云的GPU云服务器具备灵活的资源配置、高安全性和易用性,支持多种计费模式,帮助企业高效应对计算密集型任务。
1764 6
|
前端开发 Java 应用服务中间件
初始SpringBoot:详解特性和结构
SpringBoot项目结构,特性介绍(pom里的parent、start等常用到的基本都讲解了,很详细,基于官方文档讲解)
566 1
初始SpringBoot:详解特性和结构
|
网络协议 安全 网络安全
图解OSI七层模型,2024最强科普!
【7月更文挑战第20天】
3327 2
图解OSI七层模型,2024最强科普!
|
存储 网络协议 数据安全/隐私保护
OSI七层模型 (详细讲解,看这一篇就够了)
OSI七层模型 (详细讲解,看这一篇就够了)
11530 0
|
存储 关系型数据库 MySQL
PolarDB的性能对比
PolarDB的性能对比
1217 1
|
XML 存储 Java
万字+40张图带你探秘小而美的规则引擎框架LiteFlow
在每个公司的系统中,总有一些拥有复杂业务逻辑的系统,这些系统承载着核心业务逻辑,几乎每个需求都和这些核心业务有关,这些核心业务业务逻辑冗长,涉及内部逻辑运算,缓存操作,持久化操作,外部资源调取,内部其他系统RPC调用等等。时间一长,项目几经易手,维护的成本就会越来越高。各种硬代码判断,分支条件越来越多。代码的抽象,复用率也越来越低,各个模块之间的耦合度很高。一小段逻辑的变动,会影响到其他模块,需要进行完整回归测试来验证。如要灵活改变业务流程的顺序,则要进行代码大改动进行抽象,重新写方法。实时热变更业务流程,几乎很难实现。