备忘录模式 以你之姓@ 2022-09-19 12:20 207阅读 0赞 **定义:**在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样就可以将该对象恢复到原先保存的状态 **类型:**行为类 **类图:** ![1340804147_2145.jpg][] 我们在编程的时候,经常需要保存对象的中间状态,当需要的时候,可以恢复到这个状态。比如,我们使用Eclipse进行编程时,假如编写失误(例如不小心误删除了几行代码),我们希望返回删除前的状态,便可以使用Ctrl+Z来进行返回。这时我们便可以使用备忘录模式来实现。 **备忘录模式的结构** * **发起人:**记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据。 * **备忘录:**负责存储发起人对象的内部状态,在需要的时候提供发起人需要的内部状态。 * **管理角色:**对备忘录进行管理,保存和提供备忘录。 **通用代码实现** **\[java\]** [view plain][] [copy][view plain] 1. **class** Originator \{ 2. **private** String state = ""; 3. 4. **public** String getState() \{ 5. **return** state; 6. \} 7. **public****void** setState(String state) \{ 8. **this**.state = state; 9. \} 10. **public** Memento createMemento()\{ 11. **return****new** Memento(**this**.state); 12. \} 13. **public****void** restoreMemento(Memento memento)\{ 14. **this**.setState(memento.getState()); 15. \} 16. \} 17. 18. **class** Memento \{ 19. **private** String state = ""; 20. **public** Memento(String state)\{ 21. **this**.state = state; 22. \} 23. **public** String getState() \{ 24. **return** state; 25. \} 26. **public****void** setState(String state) \{ 27. **this**.state = state; 28. \} 29. \} 30. **class** Caretaker \{ 31. **private** Memento memento; 32. **public** Memento getMemento()\{ 33. **return** memento; 34. \} 35. **public****void** setMemento(Memento memento)\{ 36. **this**.memento = memento; 37. \} 38. \} 39. **public****class** Client \{ 40. **public****static****void** main(String\[\] args)\{ 41. Originator originator = **new** Originator(); 42. originator.setState("状态1"); 43. System.out.println("初始状态:"\+originator.getState()); 44. Caretaker caretaker = **new** Caretaker(); 45. caretaker.setMemento(originator.createMemento()); 46. originator.setState("状态2"); 47. System.out.println("改变后状态:"\+originator.getState()); 48. originator.restoreMemento(caretaker.getMemento()); 49. System.out.println("恢复后状态:"\+originator.getState()); 50. \} 51. \} 代码演示了一个单状态单备份的例子,逻辑非常简单:Originator类中的state变量需要备份,以便在需要的时候恢复;Memento类中,也有一个state变量,用来存储Originator类中state变量的临时状态;而Caretaker类就是用来管理备忘录类的,用来向备忘录对象中写入状态或者取回状态。 **多状态多备份备忘录** 通用代码演示的例子中,Originator类只有一个state变量需要备份,而通常情况下,发起人角色通常是一个javaBean,对象中需要备份的变量不止一个,需要备份的状态也不止一个,这就是多状态多备份备忘录。实现备忘录的方法很多,备忘录模式有很多变形和处理方式,像通用代码那样的方式一般不会用到,多数情况下的备忘录模式,是多状态多备份的。其实实现多状态多备份也很简单,最常用的方法是,我们在Memento中增加一个Map容器来存储所有的状态,在Caretaker类中同样使用一个Map容器才存储所有的备份。下面我们给出一个多状态多备份的例子: **\[java\]** [view plain][] [copy][view plain] 1. **class** Originator \{ 2. **private** String state1 = ""; 3. **private** String state2 = ""; 4. **private** String state3 = ""; 5. 6. **public** String getState1() \{ 7. **return** state1; 8. \} 9. **public****void** setState1(String state1) \{ 10. **this**.state1 = state1; 11. \} 12. **public** String getState2() \{ 13. **return** state2; 14. \} 15. **public****void** setState2(String state2) \{ 16. **this**.state2 = state2; 17. \} 18. **public** String getState3() \{ 19. **return** state3; 20. \} 21. **public****void** setState3(String state3) \{ 22. **this**.state3 = state3; 23. \} 24. **public** Memento createMemento()\{ 25. **return****new** Memento(BeanUtils.backupProp(**this**)); 26. \} 27. 28. **public****void** restoreMemento(Memento memento)\{ 29. BeanUtils.restoreProp(**this**, memento.getStateMap()); 30. \} 31. **public** String toString()\{ 32. **return**"state1="\+state1+"state2="\+state2+"state3="\+state3; 33. \} 34. \} 35. **class** Memento \{ 36. **private** Map<String, Object> stateMap; 37. 38. **public** Memento(Map<String, Object> map)\{ 39. **this**.stateMap = map; 40. \} 41. 42. **public** Map<String, Object> getStateMap() \{ 43. **return** stateMap; 44. \} 45. 46. **public****void** setStateMap(Map<String, Object> stateMap) \{ 47. **this**.stateMap = stateMap; 48. \} 49. \} 50. **class** BeanUtils \{ 51. **public****static** Map<String, Object> backupProp(Object bean)\{ 52. Map<String, Object> result = **new** HashMap<String, Object>(); 53. **try**\{ 54. BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass()); 55. PropertyDescriptor\[\] descriptors = beanInfo.getPropertyDescriptors(); 56. **for**(PropertyDescriptor des: descriptors)\{ 57. String fieldName = des.getName(); 58. Method getter = des.getReadMethod(); 59. Object fieldValue = getter.invoke(bean, **new** Object\[\]\{\}); 60. **if**(!fieldName.equalsIgnoreCase("class"))\{ 61. result.put(fieldName, fieldValue); 62. \} 63. \} 64. 65. \}**catch**(Exception e)\{ 66. e.printStackTrace(); 67. \} 68. **return** result; 69. \} 70. 71. **public****static****void** restoreProp(Object bean, Map<String, Object> propMap)\{ 72. **try** \{ 73. BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass()); 74. PropertyDescriptor\[\] descriptors = beanInfo.getPropertyDescriptors(); 75. **for**(PropertyDescriptor des: descriptors)\{ 76. String fieldName = des.getName(); 77. **if**(propMap.containsKey(fieldName))\{ 78. Method setter = des.getWriteMethod(); 79. setter.invoke(bean, **new** Object\[\]\{propMap.get(fieldName)\}); 80. \} 81. \} 82. \} **catch** (Exception e) \{ 83. e.printStackTrace(); 84. \} 85. \} 86. \} 87. **class** Caretaker \{ 88. **private** Map<String, Memento> memMap = **new** HashMap<String, Memento>(); 89. **public** Memento getMemento(String index)\{ 90. **return** memMap.get(index); 91. \} 92. 93. **public****void** setMemento(String index, Memento memento)\{ 94. **this**.memMap.put(index, memento); 95. \} 96. \} 97. **class** Client \{ 98. **public****static****void** main(String\[\] args)\{ 99. Originator ori = **new** Originator(); 100. Caretaker caretaker = **new** Caretaker(); 101. ori.setState1("中国"); 102. ori.setState2("强盛"); 103. ori.setState3("繁荣"); 104. System.out.println("===初始化状态===\\n"\+ori); 105. 106. caretaker.setMemento("001",ori.createMemento()); 107. ori.setState1("软件"); 108. ori.setState2("架构"); 109. ori.setState3("优秀"); 110. System.out.println("===修改后状态===\\n"\+ori); 111. 112. ori.restoreMemento(caretaker.getMemento("001")); 113. System.out.println("===恢复后状态===\\n"\+ori); 114. \} 115. \} **备忘录模式的优缺点和适用场景** 备忘录模式的优点有: * 当发起人角色中的状态改变时,有可能这是个错误的改变,我们使用备忘录模式就可以把这个错误的改变还原。 * 备份的状态是保存在发起人角色之外的,这样,发起人角色就不需要对各个备份的状态进行管理。 备忘录模式的缺点: * 在实际应用中,备忘录模式都是多状态和多备份的,发起人角色的状态需要存储到备忘录对象中,对资源的消耗是比较严重的。 如果有需要提供回滚操作的需求,使用备忘录模式非常适合,比如jdbc的事务操作,文本编辑器的Ctrl+Z恢复等。 [1340804147_2145.jpg]: https://img-my.csdn.net/uploads/201206/27/1340804147_2145.jpg [view plain]: http://blog.csdn.net/zhengzhb/article/details/7697549#
相关 备忘录模式 一、前言 `实现不了是研发的借口?` 实现不了,有时候是功能复杂度较高难以实现,有时候是工期较短实现不完。而编码的行为又是一个不太好量化的过程,同样一个功能每个人的实现 心已赠人/ 2022年10月16日 15:21/ 0 赞/ 14 阅读
相关 备忘录模式 备忘录模式 定义:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。 类图: ![这里写图片 「爱情、让人受尽委屈。」/ 2022年09月23日 15:52/ 0 赞/ 5 阅读
相关 备忘录模式 定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样就可以将该对象恢复到原先保存的状态 类型:行为类 类图: ![1340804147_ 以你之姓@/ 2022年09月19日 12:20/ 0 赞/ 208 阅读
相关 备忘录模式 转载:[备忘录模式 - C语言中文网][- C] 备忘录(Memento)模式的定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需 向右看齐/ 2022年09月01日 12:55/ 0 赞/ 6 阅读
相关 备忘录模式 今天无意间看到了备忘录模式,由于之前没有接触过,出于好奇,研究了一下,简单来说就是把当前状态记录下来,作为备份,用于意外情况发生恢复用的,有点类似于回退的意思。 备忘录设计 电玩女神/ 2022年08月19日 15:10/ 0 赞/ 184 阅读
相关 备忘录模式 1.使用场景: 一系列的操作之后恢复原来的状态。实际的使用场景有事务的回滚操作等。 2.UML表示 在备忘录模式中有以下的几种对象: 2.1源发器:Origi 骑猪看日落/ 2022年05月31日 09:26/ 0 赞/ 243 阅读
相关 备忘录模式 备忘录模式 一、概述 1. 就是保存某个对象内部状态的拷贝,这样以后就可以将该对象恢复到 原先的状态。 2. 结构 源发器类Origin 「爱情、让人受尽委屈。」/ 2022年04月17日 00:21/ 0 赞/ 249 阅读
相关 备忘录模式 前言 备忘录(Memento),在不破坏封装的前提下,捕获一个对象的内不状态,并在该对象之外保存这个状态 ,这样以后就可将该对象恢复到原来保存的状态。 一、发起人 一时失言乱红尘/ 2021年12月09日 00:49/ 0 赞/ 302 阅读
相关 备忘录模式 一 点睛 备忘录模式提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原,很多软件 爱被打了一巴掌/ 2021年07月24日 22:49/ 0 赞/ 496 阅读
相关 备忘录模式 忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。 介绍 **意图**:在不破坏封装性的前提下... 小灰灰/ 2020年06月13日 05:38/ 0 赞/ 741 阅读
还没有评论,来说两句吧...