设计模式系列-第二十二章(行为型-备忘录模式)

一、备忘录模式的定义

    备忘录模式,也叫快照(Snapshot)模式。在不违背封装原则的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便之后恢复对象为先前的状态。这个模式的定义主要表达了两部分内容。一部分是,存储副本以便后期恢复。这一部分很好理解。另一部分是,要在不违背封装原则的前提下,进行对象的备份和恢复。 

二、备忘录模式实现

    示例一个小程序,可以接收命令行的输入。用户输入文本时,程序将其追加存储在内存文本中;用户输入“:list”,程序在命令行中输出内存文本的内容;用户输入“:undo”,程序会撤销上一次输入的文本,也就是从内存文本中将上次输入的文本删除掉。如何进行代码设计呢?

    我们定义输入文本类InputText ,为了能用快照恢复 InputText 对象,我们在 InputText 类中定义了 setText() 函数。但这样是违背封装的原则的,理论上快照本身是不可变的,不应该包含任何 set() 等修改内部状态的函数。所以,我们定义一个独立的类(Snapshot 类)来表示快照,而不是复用 InputText 类。这个类只暴露 get() 方法,没有 set() 等任何修改内部状态的方法。其二,在 InputText 类中,我们把 setText() 方法重命名为 restoreSnapshot() 方法,用意更加明确,只用来恢复对象。


public class InputText {
  private StringBuilder text = new StringBuilder();

  public String getText() {
    return text.toString();
  }

  public void append(String input) {
    text.append(input);
  }

  public Snapshot createSnapshot() {
    return new Snapshot(text.toString());
  }

  public void restoreSnapshot(Snapshot snapshot) {
    this.text.replace(0, this.text.length(), snapshot.getText());
  }
}

public class Snapshot {
  private String text;

  public Snapshot(String text) {
    this.text = text;
  }

  public String getText() {
    return this.text;
  }
}

public class SnapshotHolder {
  private Stack<Snapshot> snapshots = new Stack<>();

  public Snapshot popSnapshot() {
    return snapshots.pop();
  }

  public void pushSnapshot(Snapshot snapshot) {
    snapshots.push(snapshot);
  }
}

public class ApplicationMain {
  public static void main(String[] args) {
    InputText inputText = new InputText();
    SnapshotHolder snapshotsHolder = new SnapshotHolder();
    Scanner scanner = new Scanner(System.in);
    while (scanner.hasNext()) {
      String input = scanner.next();
      if (input.equals(":list")) {
        System.out.println(inputText.toString());
      } else if (input.equals(":undo")) {
        Snapshot snapshot = snapshotsHolder.popSnapshot();
        inputText.restoreSnapshot(snapshot);
      } else {
        snapshotsHolder.pushSnapshot(inputText.createSnapshot());
        inputText.append(input);
      }
    }
  }
}

三、备忘录模式和备份

    备份在我们平时的开发中更常听到。那备忘录模式跟“备份”有什么区别和联系呢?实际上,这两者的应用场景很类似,都应用在防丢失、恢复、撤销等场景中。它们的区别在于,备忘录模式更侧重于代码的设计和实现,备份更侧重架构设计或产品设计。

     假设每当有数据改动,我们都需要生成一个备份,以备之后恢复。如果需要备份的数据很大,这样高频率的备份,不管是对存储(内存或者硬盘)的消耗,还是对时间的消耗,都可能是无法接受的。想要解决这个问题,我们一般会采用“低频率全量备份”和“高频率增量备份”相结合的方法。全量备份就不用讲了,它跟我们上面的例子类似,就是把所有的数据“拍个快照”保存下来。所谓“增量备份”,指的是记录每次操作或数据变动。当我们需要恢复到某一时间点的备份的时候,如果这一时间点有做全量备份,我们直接拿来恢复就可以了。如果这一时间点没有对应的全量备份,我们就先找到最近的一次全量备份,然后用它来恢复,之后执行此次全量备份跟这一时间点之间的所有增量备份,也就是对应的操作或者数据变动。这样就能减少全量备份的数量和频率,减少对时间、内存的消耗。重点回顾

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值