備忘錄模式(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 Memento20 {21 private string _state;22 23 public Memento(string state)24 {25 this._state = state;26 }27 28 public string State29 {30 get { return _state; }31 }32 }33 34 /// <summary>35 /// 發起人36 /// </summary>37 public class Originator38 {39 private string _state;40 41 public string State42 {43 get44 {45 return _state;46 }47 set48 {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 Caretaker70 {71 private Memento _memento;72 73 public Memento Memento74 {75 get76 {77 return _memento;78 }79 set80 {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)提供一個可回滾的操作,
參考:https://blog.csdn.net/heyangyi_19940703/article/details/51376570
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/39942.html
標籤:設計模式
下一篇:設計模式-行為型-解釋器模式
