设计模式-行为型-备忘录模式

原理和实现

备忘录模式,也叫快照(Snapshot)模式,英文翻译是 Memento Design Pattern。在 GoF 的《设计模式》一书中,备忘录模式是这么定义的: 在不违背封装原则的前提下,捕获一个对象的内部状态,并在该对象之外 保存这个状态,以便之后恢复对象为先前的状态。

场景及实现

假设有这样一道面试题,希望你编写一个小程序,可以接收命令行的输入。用户输入文本时,程序将其追加存储在内存文本中;用户输入“:list”,程序在命令行中输出内存文本的 内容;用户输入“:undo”,程序会撤销上一次输入的文本,也就是从内存文本中将上次输 入的文本删除掉。

我举了个小例子来解释一下这个需求,如下所示:

实现如下:

上面代码实现过程中,有两处缺陷,第一,为了能用快照恢复 InputText 对象,我们在 InputText 类中定义了 setText() 函 数,但这个函数有可能会被其他业务使用,所以,暴露不应该暴露的函数违背了封装原则;

第二,快照本身是不可变的,理论上讲,不应该包含任何 set() 等修改内部状态的函数, 但在上面的代码实现中,“快照“这个业务模型复用了 InputText 类的定义,而 InputText 类本身有一系列修改内部状态的函数,所以,用 InputText 类来表示快照违背了封装原则。

快照模式优化及实现

针对以上问题,我们对代码做两点修改。其一,定义一个独立的类(Snapshot 类)来表示快照,而不是复用 InputText 类。这个类只暴露 get() 方法,没有 set() 等任何修改内部状态的方法。其二,在 InputText 类中,我们把 setText() 方法重命名为 restoreSnapshot() 方法,用意更加明确,只用来恢复对象。

总结

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

备忘录模式的应用场景也比较明确和有限,主要是用来防丢失、撤销、恢复等。它跟平时我们常说的“备份”很相似。两者的主要区别在于,备忘录模式更侧重于代码的设计和实现, 备份更侧重架构设计或产品设计。