Java设计模式—备忘录模式(快照模式)

发布于:2024-03-29 ⋅ 阅读:(21) ⋅ 点赞:(0)

定义 

        备忘录模式提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原,很多软件都提供了撤销(Undo)操作,如 Word、记事本、Photoshop、IDEA等软件在编辑时按 Ctrl+Z 组合键时能撤销当前操作,使文档恢复到之前的状态;还有在 浏览器 中的后退键、数据库事务管理中的回滚操作、玩游戏时的中间结果存档功能、数据库与操作系统的备份操作、棋类游戏中的悔棋功能等都属于这类。  

组成结构

备忘录模式的主要角色如下:

发起人(Originator)角色:

记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。

备忘录(Memento)角色:

负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。

管理者(Caretaker)角色:

对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。

备忘录有两个等效的接口:

窄接口:管理者(Caretaker)对象(和其他发起人对象之外的任何对象)看到的是备忘录的窄接口(narror Interface),这个窄接口只允许他把备忘录对象传给其他的对象。
宽接口:与管理者看到的窄接口相反,发起人对象可以看到一个宽接口(wide Interface),这个宽接口允许它读取所有的数据,以便根据这些数据恢复这个发起人对象的内部状态。

package debug01;

public class debug01 {
    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());
    }
}
  • debug01 类是程序的入口点,其中包含 main 方法。
  • 在 main 方法中,首先创建了 Originator 和 CareTaker 的实例。
  • 然后,originator 对象的状态被设置为 "State #1"、"State #2"、"State #3" 和 "State #4",并且在每次状态更改后,将当前状态保存到 careTaker 中。
  • 最后,打印出最后设置的状态以及通过 careTaker 恢复的两个先前保存的状态。
package debug01;

import java.util.*;

public class CareTaker {
    private List<Memento> mementoList = new ArrayList<Memento>();

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

    public Memento get(int index) {
        return mementoList.get(index);
    }
}
  • CareTaker 类负责保存 Originator 的状态。它使用一个 List 来存储 Memento 对象。
  • add 方法用于向 mementoList 中添加状态。
  • get 方法用于获取指定索引位置的 Memento 对象。
package debug01;

public class Originator {
    private String state;

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

    public String getState() {
        return state;
    }

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

    public void getStateFromMemento(Memento memento) {
        state = memento.getState();
    }
}
  • Originator 类是原始对象,其中包含了要保存的状态。
  • setState 方法用于设置状态。
  • getState 方法用于获取状态。
  • saveStateToMemento 方法创建并返回一个新的 Memento 对象,该对象包含了当前状态的副本。
  • getStateFromMemento 方法用于从 Memento 对象中恢复状态。

package debug01;
public class Memento {
    private String state;
    public Memento(String state) {
        this.state = state;
    }
    public String getState() {
        return state;
    }
}
  • Memento 类用于存储 Originator 的状态。
  • 它有一个带有状态参数的构造函数,用于初始化状态。
  • getState 方法用于获取状态的值。

整个代码实现了备忘录模式,用于保存和恢复对象的状态。

优缺点

优点:

- 提供了一种可以恢复状态的机制。当用户需要时能够比较方便地将数据恢复到某个历史的状态。
- 实现了内部状态的封装。除了创建它的发起人之外,其他对象都不能够访问这些状态信息。
- 简化了发起人类。发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则。

缺点:

- 资源消耗大。如果要保存的内部状态信息过多或者特别频繁,将会占用比较大的内存资源。

使用场景

- 需要保存与恢复数据的场景,如玩游戏时的中间结果的存档功能。
- 需要提供一个可回滚操作的场景,如 Word、记事本、Photoshop,idea等软件在编辑时按 Ctrl+Z 组合键,还有数据库中事务操作。

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到