diff --git a/notes/pics/dp-memento.png b/notes/pics/dp-memento.png index 097a2234..9290b94b 100644 Binary files a/notes/pics/dp-memento.png and b/notes/pics/dp-memento.png differ diff --git a/notes/设计模式 - 备忘录.md b/notes/设计模式 - 备忘录.md index 0c27b4ce..355eb54e 100644 --- a/notes/设计模式 - 备忘录.md +++ b/notes/设计模式 - 备忘录.md @@ -4,27 +4,31 @@ 在不违反封装的情况下获得对象的内部状态,从而在需要时可以将对象恢复到之前保存的状态。 ### 类图 -- Originator:原始对象 -- Caretaker:负责保存好备忘录 -- Memento:备忘录,存储原始对象的状态。备忘录实际上有两个接口,一个是提供给 Caretaker 的窄接口:它只能将备忘录传递给其它对象;一个是提供给 Originator 的宽接口,允许它访问到先前状态所需的所有数据。理想情况是只允许 Originator 访问本备忘录的内部状态。 +- Originator:原始对象,负责创建备忘录和用备忘录恢复状态; +- Caretaker:负责保存好备忘录; +- Memento:备忘录,存储原始对象的状态。 + +备忘录对外提供两个接口:提供给 Caretaker 的窄接口,只能保存和传递备忘录,看不到其中的数据;提供给 Originator 的宽接口,可以读出恢复状态所需的所有数据。这样 Caretaker 保管备忘录时不依赖其中的数据,也不会破坏封装。
- * Note that this object implements both interfaces to Originator and CareTaker + * 备忘录实现,同时实现了宽接口和窄接口 */ public class PreviousCalculationImp implements PreviousCalculationToCareTaker, PreviousCalculationToOriginator { @@ -126,37 +126,28 @@ public class PreviousCalculationImp implements PreviousCalculationToCareTaker, ```java /** - * CareTaker object + * Caretaker */ public class Client { public static void main(String[] args) { - // program starts Calculator calculator = new CalculatorImp(); - // assume user enters two numbers + // 用户输入两个数 calculator.setFirstNumber(10); calculator.setSecondNumber(100); - - // find result System.out.println(calculator.getCalculationResult()); - // Store result of this calculation in case of error + // 保存这次计算,以便出错时恢复 PreviousCalculationToCareTaker memento = calculator.backupLastCalculation(); - // user enters a number + // 用户输入了一个错误的数 calculator.setFirstNumber(17); - - // user enters a wrong second number and calculates result calculator.setSecondNumber(-290); - - // calculate result System.out.println(calculator.getCalculationResult()); - // user hits CTRL + Z to undo last operation and see last result + // 用户按下 Ctrl + Z,恢复到上一次计算 calculator.restorePreviousCalculation(memento); - - // result restored System.out.println(calculator.getCalculationResult()); } } @@ -169,9 +160,9 @@ public class Client { ``` ### JDK 中的应用 -- java.io.Serializable +javax.swing.undo.StateEdit 用到了同样的思路:被编辑的对象实现 StateEditable,修改前后由对象把自己的状态写入 Hashtable,撤销或重做时再用它恢复。序列化可以用来把备忘录保存到文件中,但 Serializable 只是一个标记接口,本身不构成备忘录。 ## 参考资料 - 弗里曼. Head First 设计模式 [M]. 中国电力出版社, 2007. -- Gamma E. 设计模式: 可复用面向对象软件的基础 [M]. 机械工业出版社, 2007. +- Gamma E. 设计模式:可复用面向对象软件的基础 [M]. 机械工业出版社, 2007.