设计模式-行为型-备忘录模式
程序员文章站
2023-11-18 22:30:16
备忘录模式(Memento): 后悔药来啦!!!备忘录模式在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便在需要时能将该对象恢复到原先保存的状态。 备忘录模式的角色: 1)发起人(Originator):记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能 ......
备忘录模式(memento):
后悔药来啦!!!备忘录模式在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便在需要时能将该对象恢复到原先保存的状态。
备忘录模式的角色:
1)发起人(originator):记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。
2)备忘录(memento):负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。
3)管理者(caretaker):对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。
根据上述uml图实现代码:
1 internal class program 2 { 3 private static void main(string[] args) 4 { 5 originator o = new originator(); 6 o.state = "on"; 7 8 caretaker c = new caretaker(); 9 c.memento = o.creatememento(); 10 11 o.state = "off"; 12 o.setmemento(c.memento); 13 } 14 } 15 16 /// <summary> 17 /// 备忘录 18 /// </summary> 19 public class memento 20 { 21 private string _state; 22 23 public memento(string state) 24 { 25 this._state = state; 26 } 27 28 public string state 29 { 30 get { return _state; } 31 } 32 } 33 34 /// <summary> 35 /// 发起人 36 /// </summary> 37 public class originator 38 { 39 private string _state; 40 41 public string state 42 { 43 get 44 { 45 return _state; 46 } 47 set 48 { 49 _state = value; 50 console.writeline("state = " + _state); 51 } 52 } 53 54 public memento creatememento() 55 { 56 return (new memento(_state)); 57 } 58 59 public void setmemento(memento memento) 60 { 61 console.writeline("restoring state..."); 62 state = memento.state; 63 } 64 } 65 66 /// <summary> 67 /// 管理者 68 /// </summary> 69 public class caretaker 70 { 71 private memento _memento; 72 73 public memento memento 74 { 75 get 76 { 77 return _memento; 78 } 79 set 80 { 81 _memento = value; 82 } 83 } 84 }
现实生活中,我们往往会进行文档的备份或者svn,git的快照。
1 internal class program 2 { 3 private static void main(string[] args) 4 { 5 list<document> docs = new list<document>() 6 { 7 new document{ name="水浒传", content="水浒传123131231" }, 8 new document{ name="三国演义", content="三国演义111111" } 9 }; 10 11 originator originator = new originator(docs); 12 caretaker caretaker = new caretaker(); 13 datetimeoffset time1 = new datetimeoffset(datetime.now); 14 caretaker.mementodic.add(time1, originator.creatememento()); 15 originator.getshow(); 16 console.writeline("===================================="); 17 console.writeline("修改内容"); 18 docs[0].content = "新水浒,搞笑ing"; 19 datetimeoffset time2 = new datetimeoffset(datetime.now); 20 caretaker.mementodic.add(time2, originator.creatememento()); 21 originator.getshow(); 22 console.writeline("===================================="); 23 console.writeline("回滚到第一阶段"); 24 originator.setmemento(caretaker.mementodic[time1]); 25 originator.getshow(); 26 console.writeline("回滚到第二阶段"); 27 originator.setmemento(caretaker.mementodic[time2]); 28 originator.getshow(); 29 } 30 } 31 32 /// <summary> 33 /// 文件 34 /// </summary> 35 public class document 36 { 37 public string name { get; set; } 38 public string content { get; set; } 39 } 40 41 /// <summary> 42 /// 备忘录 43 /// </summary> 44 public class memento 45 { 46 public list<document> fileback; 47 48 public memento(list<document> docs) 49 { 50 this.fileback = docs; 51 } 52 } 53 54 /// <summary> 55 /// 发起人 56 /// </summary> 57 public class originator 58 { 59 //内部状态 60 public list<document> docs; 61 62 public originator(list<document> docs) 63 { 64 this.docs = docs; 65 } 66 67 public memento creatememento() 68 { 69 // 深拷贝传递对象 70 var str = jsonconvert.serializeobject(this.docs); 71 return new memento(jsonconvert.deserializeobject<list<document>>(str)); 72 } 73 74 public void setmemento(memento memento) 75 { 76 console.writeline("restoring state..."); 77 docs = memento.fileback; 78 } 79 80 /// <summary> 81 /// 显示信息 82 /// </summary> 83 public void getshow() 84 { 85 foreach (var doc in docs) 86 { 87 console.writeline($"文件名:{doc.name},内容:{doc.content}"); 88 } 89 } 90 } 91 92 /// <summary> 93 /// 管理者 94 /// </summary> 95 public class caretaker 96 { 97 // 使用多个备忘录来存储多个备份点 98 public dictionary<datetimeoffset, memento> mementodic { get; set; } 99 100 public caretaker() 101 { 102 mementodic = new dictionary<datetimeoffset, memento>(); 103 } 104 }
备忘录模式的优缺点:
优点:
1)给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。
2)实现了信息的封装,使得用户不需要关心状态的保存细节。
缺点:消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。
备忘录模式的应用场景:
1)需要保存/恢复数据的相关状态场景。
2)提供一个可回滚的操作。
参考:
上一篇: vue模板语法-插值详解
下一篇: PHP判断指定时间段的2个方法