《设计模式之备忘录模式》由会员分享,可在线阅读,更多相关《设计模式之备忘录模式(6页珍藏版)》请在金锄头文库上搜索。
1、 1 / 6 设计模式之备忘录模式 定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样就可以将该对象恢复到原先保存的状态 类型:行为类 类图: 我们在编程的时候,经常需要保存对象的中间状态,当需要的时候,可以恢复到这个状态。比如,我们使用 Eclipse 进行编程时,假如编写失误(例如不小心误删除了几行代码),我们希望返回删除前的状态,便可以使用 Ctrl+Z 来进行返回。这时我们便可以使用备忘录模式来实现。 备忘录模式的结构 发起人:记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据。 备忘录:负责存储发起人对象的内部状态,在
2、需要的时候提供发起人需要的内部状态。 管理角色:对备忘录进行管理,保存和提供备忘录。 通用代码实现 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
3、void restoreMemento(Memento memento) 14. this.setState(memento.getState(); 15. 16. 2 / 6 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
4、.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
5、= 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. origi
6、nator.restoreMemento(caretaker.getMemento(); 49. System.out.println(“恢复后状态:“+originator.getState(); 50. 51. 代码演示了一个单状态单备份的例子, 逻辑非常简单: Originator 类中的 state 变量需要备份, 以便在需要的时候恢复;Memento 类中,也有一个 state 变量,用来存储 Originator 类中 state 变量的临时状态;而 Caretaker 类就是用来管理备忘录类的,用来向备忘录对象中写入状态或者取回状态。 多状态多备份备忘录 3 / 6 通用代码演示
7、的例子中, Originator 类只有一个 state 变量需要备份, 而通常情况下, 发起人角色通常是一个 javaBean,对象中需要备份的变量不止一个,需要备份的状态也不止一个,这就是多状态多备份备忘录。实现备忘录的方法很多,备忘录模式有很多变形和处理方式,像通用代码那样的方式一般不会用到,多数情况下的备忘录模式,是多状态多备份的。其实实现多状态多备份也很简单,最常用的方法是,我们在 Memento 中增加一个 Map 容器来存储所有的状态,在 Caretaker类中同样使用一个 Map 容器才存储所有的备份。下面我们给出一个多状态多备份的例子: 1. class Originator
8、 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
9、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 memen
10、to) 29. BeanUtils.restoreProp(this, memento.getStateMap(); 30. 31. public String toString() 32. return “state1=“+state1+“state2=“+state2+“state3=“+state3; 33. 34. 35. class Memento 4 / 6 36. private Map stateMap; 37. 38. public Memento(Map map) 39. this.stateMap = map; 40. 41. 42. public Map getStat
11、eMap() 43. return stateMap; 44. 45. 46. public void setStateMap(Map stateMap) 47. this.stateMap = stateMap; 48. 49. 50. class BeanUtils 51. public static Map backupProp(Object bean) 52. Map result = new HashMap(); 53. try 54. BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass(); 55. Property
12、Descriptor 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 propMap) 72. try 73. BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass(); 74. PropertyDescriptor d