当前位置: 移动技术网 > IT编程>软件设计>设计模式 > 设计模式-行为型-备忘录模式

设计模式-行为型-备忘录模式

2019年10月10日  | 移动技术网IT编程  | 我要评论

备忘录模式(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)提供一个可回滚的操作。

参考:

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网