六 行为型-备忘录模式

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。
小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

image.png

定义

备忘录这个词汇大家应该都不陌生,我就经常使用备忘录来记录一些比较重要的或者容易遗忘的信息,与之相关的最常见的应用有许多,比如游戏存档,我们玩游戏的时候肯定有存档功能,旨在下一次登录游戏时可以从上次退出的地方继续游戏,或者对复活点进行存档,如果挂掉了则可以读取复活点的存档信息重新开始。与之相类似的就是数据库的事务回滚,或者重做日志redo log等。

  备忘录模式(Memento) ,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存着这个状态。这样以后就可将该对象恢复到原先保存的状态。UML结构图如下:

image.png 其中,Originator是发起人,负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态;Memento是备忘录,负责存储Originator对象的内部状态,并可防止Originator以外的其他对象访问备忘录Memento;Caretaker是管理者,负责保存好备忘录的Memento,不能对备忘录的内容进行操作或检查。

1. 发起人角色

  记录当前时刻的内部状态,并负责创建和恢复备忘录数据,允许访问返回到先前状态所需的所有数据。

 public class Originator {

    private String state;

    public String getState() {
        return state;
    }

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

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

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

    public void show() {
        System.out.println("state = " + state);
    }

}
复制代码

2. 备忘录角色

  负责存储Originator发起人对象的内部状态,在需要的时候提供发起人需要的内部状态。

public class Memento {

  private String state;

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

  public String getState() {
      return state;
  }

}
复制代码

3. 备忘录管理员角色

  对备忘录进行管理、保存和提供备忘录,只能将备忘录传递给其他角色。

public class Caretaker {

  private Memento memento;

  public Memento getMemento() {
      return memento;
  }

  public void setMemento(Memento memento) {
      this.memento = memento;
  }

}
复制代码

4. Client客户端

  下面编写一小段代码测试一下,即先将状态置为On,保存后再将状态置为Off,然后通过备忘录管理员角色恢复初始状态。

public class Client {

  public static void main(String[] args) {
      Originator originator = new Originator();
      originator.setState("On");    //Originator初始状态
      originator.show();

      Caretaker caretaker = new Caretaker();
      caretaker.setMemento(originator.createMento());

      originator.setState("Off");    //Originator状态变为Off
      originator.show();

      originator.setMemento(caretaker.getMemento());    //回复初始状态
      originator.show();
  }

}
复制代码

image.png

备忘录模式的应用

1. 何时使用

  • 需要记录一个对象的内部状态时,为了允许用户取消不确定或者错误的操作,能够恢复到原先的状态

2. 方法

  • 通过一个备忘录类专门存储对象状态

3. 优点

  • 给用户提供了一种可以恢复状态的机制,可以使用能够比较方便地回到某个历史的状态
  • 实现了信息的封装,使得用户不需要关心状态的保存细节

4. 缺点

  • 消耗资源

5. 使用场景

  • 需要保存和恢复数据的相关场景
  • 提供一个可回滚的操作,如ctrl+z、浏览器回退按钮、Backspace键等
  • 需要监控的副本场景

6. 应用实例

  • 游戏存档
  • ctrl+z键、浏览器回退键等(撤销/还原)
  • 棋盘类游戏的悔棋
  • 数据库事务的回滚

猜你喜欢

转载自juejin.im/post/7019443205665980452