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

👈️上一篇:观察者模式
设计模式-专栏👈️

文章目录

备忘录模式

备忘录模式(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(负责人)

负责保存好备忘录。

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

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

类图

代码示例

java 复制代码
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. 数据库事务管理:在数据库事务处理中,如果一系列操作不能全部完成,就需要回滚操作,将数据恢复到操作之前的状态。

👈️上一篇:观察者模式
设计模式-专栏👈️

相关推荐
坐吃山猪4 小时前
SpringBoot01-配置文件
java·开发语言
我叫汪枫4 小时前
《Java餐厅的待客之道:BIO, NIO, AIO三种服务模式的进化》
java·开发语言·nio
yaoxtao4 小时前
java.nio.file.InvalidPathException异常
java·linux·ubuntu
Swift社区6 小时前
从 JDK 1.8 切换到 JDK 21 时遇到 NoProviderFoundException 该如何解决?
java·开发语言
DKPT7 小时前
JVM中如何调优新生代和老生代?
java·jvm·笔记·学习·spring
phltxy7 小时前
JVM——Java虚拟机学习
java·jvm·学习
seabirdssss8 小时前
使用Spring Boot DevTools快速重启功能
java·spring boot·后端
喂完待续8 小时前
【序列晋升】29 Spring Cloud Task 微服务架构下的轻量级任务调度框架
java·spring·spring cloud·云原生·架构·big data·序列晋升
benben0448 小时前
ReAct模式解读
java·ai