图1-1 黑箱备忘录模式
MementoIF是一个窄接口也是一个标识接口。Memento备忘者是Originator发起者的内部类,由于Memento的方法都是私有的,所以只有发起者能够调用Memento的方法,Caretaker负责人是没法调用的。这是一个安全性的设计。是JAVA双重接口(宽窄接口)的一个巧妙实现。
下面的例子改编自《Java与模式》
public class Originator { private String state; /** * 返回一个备忘录实例 * @return */ public MementoIF createMemento() { return new Memento(this.state); } /** * 恢复状态 * @param memento */ public void restoreMemento(MementoIF memento) { Memento m = (Memento) memento; this.setState(m.getState()); } public String getState() { return this.state; } public void setState(String state) { this.state = state; } /** * 内部成员类,备忘录 */ protected class Memento implements MementoIF { private String savedState; private Memento(String someState) { this.savedState = someState; } private void setState(String someState) { this.savedState = someState; } private String getState() { return this.savedState; } } }
public class Caretaker { private MementoIF memento; public MementoIF getMemento() { return memento; } public void setMemento(MementoIF memento) { this.memento = memento; } }
public interface MementoIF { }
public class Client { private static Originator o = new Originator(); private static Caretaker c = new Caretaker(); public static void main(String[] args) { o.setState("a"); c.setMemento(o.createMemento()); o.setState("b"); System.out.println(o.getState()); o.restoreMemento(c.getMemento()); System.out.println(o.getState()); } }
b
a
以上我们就实现了一个黑箱-备忘录设计模式的模型。在当前设计中负责人的角色不包括备忘录的创建和状态的恢复,这两个责任是由客户端角色直接当用发起者和备忘录角色做到的。
如果能让负责人调用备忘录角色和发起人角色,进行备忘录的创建和恢复,那么客户端便不在需要协调备忘录角色和发起人角色。
除了负责人角色,其他的类没有变化,所以下面仅给出增强负责人的实现代码
/** * 增强的负责人,负责对备忘录的创建和恢复 */ public class StrongCaretaker { private Originator originator; private MementoIF memento; StrongCaretaker(Originator originator) { this.originator = originator; } public void createMemento() { this.memento = originator.createMemento(); } public void restoreMemento() { originator.restoreMemento(this.memento); } public Originator getOriginator() { return originator; } public void setOriginator(Originator originator) { this.originator = originator; } public MementoIF getMemento() { return memento; } public void setMemento(MementoIF memento) { this.memento = memento; } }
public class Client { private static Originator o = new Originator(); private static StrongCaretaker sc = new StrongCaretaker(o); public static void main(String[] args) { o.setState("aaa"); sc.createMemento(); o.setState("bbb"); System.out.println(o.getState()); sc.restoreMemento(); System.out.println(o.getState()); } }
bbb
aaa