概述
备忘录模式是为了在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后这个对象可以恢复到原先保存的状态。
备忘录模式引入一个存储状态的备忘录对象,它存储另一个对象在某个瞬时的内部状态。为了让外部无法访问这个对象的值一般把这个对象实现成为需要保存数据的对象的私有内部类。这样一来除了这个需要保存数据的对象,外部无法访问到这个备忘录对象的数据。
备忘录模式的组成
备忘录模式中有三个主要对象:
- 备忘录对象:主要用来存储Originator对象的内部状态,另外它只能由Originator对象来访问它内部的数据,Originator 外部的对象不应该访问到备忘录对象内部的数据。
- Originator对象:可以创建备忘录对象来保存某个时刻自身的状态,也可以使用备忘录来恢复内部状态。
- 备忘录管理对象:负责保存备忘录对象,虽然管理者能够存取备忘录对象,但是它不能访问备忘录对象的内部数据。
并不是一定要特别设定一个管理者对象,调用Originator 获得备忘录对象后,备忘录对象存放在哪里,哪个对象就可以算得上是管理者对象。管理者对象并不是只能管理一个备忘录对象,一个管理对象可以管理很多备忘录对象。并且还可以是多个不同类型的备忘录对象。
如果需要频繁创建备忘录对象,并且创建和应用备忘录对象来恢复状态的顺序是可控的,那么可以让备忘录进行增量存储,也就是备忘录仅仅存储Originator 内部相对于上一次存储状态后的增量改变。
如果在Originator 创建备忘录对象的时候,如果Originator对象中全部或者大部分的状态都需要保存,一个简单的方式就是直接克隆一个Originator对象,这时候备忘录对象中存放的就是一个Originator对象的实例。
从备忘录模式的功能和实现上,是可以把备忘录的数据实现成为离线存储的,也就是不仅仅限于存储在内存中,还可以把这些数据存储到文件中XML中数据库中。从而实现跨越会话的备份和恢复功能。
当然并不是所有的备份数据都需要离线存储,一般来讲需要存储很长时间,或者需要支持跨越会话的备份和恢复功能,或者希望系统关闭后还能被保存的备份数据的情况下使用离线备份。
离线备份的实现,只需要修改管理者对象,把保存备忘录对象的方法实现成为保存到文件中,而恢复对象实现成为读取文件就可以了,而对于其他的相关对象,主要是实现序列化,通过序列化来将对象存储到文件中。
public interface Memento { }
|
public class Originator { private String mState = null; public Originator(String state) { mState = state; } public void runSomeOperationBeforeBackup(String state) { this.mState = state; } public void reportState() { System.out.println(mState); } private static class MementoImp implements Memento { private String backupState = null; public MementoImp(String backupState) { this.backupState = backupState; } public String getState() { return this.backupState; } } public Memento backUpState() { return new MementoImp(this.mState); } public void restoreState(Memento memento) { this.mState = ((MementoImp)memento).getState(); } }
|
public class MementoManger { private Memento mMemento = null; public void saveMemento(Memento memento) { mMemento = memento; } public Memento getMemento() { return this.mMemento; } }
|
public class Client { public static void main(String[] args) { Originator originator = new Originator("初始状态"); originator.runSomeOperationBeforeBackup("运行一段时间后的状态"); Memento memento = originator.backUpState(); MementoManger manager = new MementoManger(); manager.saveMemento(memento); originator.runSomeOperationBeforeBackup("再次运行一段时间后的状态"); originator.reportState(); Memento memento1 = manager.getMemento(); originator.restoreState(memento1); originator.reportState(); } }
|