From 05709db77e620536d94e662b4d620d7039cd40ee Mon Sep 17 00:00:00 2001 From: Petrutiu Mihai Date: Thu, 23 Jun 2016 21:03:26 +0300 Subject: [PATCH] Add another example of the memento pattern --- .../EmployeeSerialized/Caretaker.cs | 30 ++++++++++++++ .../EmployeeSerialized/Employee.cs | 33 +++++++++++++++ .../EmployeeSerialized/EmployeeMemento.cs | 20 +++++++++ .../EmployeeSerializedExample.cs | 41 +++++++++++++++++++ .../EmployeeSerialized/LimitedSizeStack.cs | 31 ++++++++++++++ src/MememntoPattern/MementoPatternExamples.cs | 18 ++++++++ src/MememntoPattern/project.json | 3 +- 7 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 src/MememntoPattern/EmployeeSerialized/Caretaker.cs create mode 100644 src/MememntoPattern/EmployeeSerialized/Employee.cs create mode 100644 src/MememntoPattern/EmployeeSerialized/EmployeeMemento.cs create mode 100644 src/MememntoPattern/EmployeeSerialized/EmployeeSerializedExample.cs create mode 100644 src/MememntoPattern/EmployeeSerialized/LimitedSizeStack.cs diff --git a/src/MememntoPattern/EmployeeSerialized/Caretaker.cs b/src/MememntoPattern/EmployeeSerialized/Caretaker.cs new file mode 100644 index 0000000..c2aeb23 --- /dev/null +++ b/src/MememntoPattern/EmployeeSerialized/Caretaker.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace MememntoPattern.EmployeeSerialized +{ + /// + /// Caretaker + /// + public class Caretaker + { + private LimitedSizeStack employeeHistory; + + public Caretaker() + { + employeeHistory = new LimitedSizeStack(10); + } + + public void Save(Employee emp) + { + employeeHistory.Push(emp.Save()); + } + + public void Revert(Employee emp) + { + emp.Revert(employeeHistory.Pop()); + } + } +} diff --git a/src/MememntoPattern/EmployeeSerialized/Employee.cs b/src/MememntoPattern/EmployeeSerialized/Employee.cs new file mode 100644 index 0000000..b85909b --- /dev/null +++ b/src/MememntoPattern/EmployeeSerialized/Employee.cs @@ -0,0 +1,33 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace MememntoPattern.EmployeeSerialized +{ + /// + /// Originator + /// + public class Employee + { + public string Name { get; set; } + + public string Address { get; set; } + + public List Phones { get; set; } + + public EmployeeMemento Save() + { + return new EmployeeMemento(JsonConvert.SerializeObject(this)); + } + + public void Revert(EmployeeMemento memento) + { + Employee newEmployee = JsonConvert.DeserializeObject(memento.SerializedEmployee); + Name = newEmployee.Name; + Address = newEmployee.Address; + Phones = newEmployee.Phones; + } + } +} diff --git a/src/MememntoPattern/EmployeeSerialized/EmployeeMemento.cs b/src/MememntoPattern/EmployeeSerialized/EmployeeMemento.cs new file mode 100644 index 0000000..665fbe3 --- /dev/null +++ b/src/MememntoPattern/EmployeeSerialized/EmployeeMemento.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace MememntoPattern.EmployeeSerialized +{ + /// + /// Memento object + /// + public class EmployeeMemento + { + public string SerializedEmployee; + + public EmployeeMemento(string serializedEmployee) + { + SerializedEmployee = serializedEmployee; + } + } +} diff --git a/src/MememntoPattern/EmployeeSerialized/EmployeeSerializedExample.cs b/src/MememntoPattern/EmployeeSerialized/EmployeeSerializedExample.cs new file mode 100644 index 0000000..9e378e9 --- /dev/null +++ b/src/MememntoPattern/EmployeeSerialized/EmployeeSerializedExample.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace MememntoPattern.EmployeeSerialized +{ + public class EmployeeSerializedExample + { + public void Run() + { + Caretaker caretaker = new Caretaker(); + Employee e = new Employee(); + e.Name = "Ghiuri"; + e.Address = "Stairway to heaven"; + + Console.WriteLine("First saved address: {0}", e.Address); + caretaker.Save(e); + + e.Address = "Highway to hell"; + + Console.WriteLine("Last saved address: {0}", e.Address); + + caretaker.Save(e); + + e.Address = "Home of the brave"; // No save, no home, no address + + Console.WriteLine("Address before revert: {0}", e.Address); + + caretaker.Revert(e); + + Console.WriteLine("First reverted Address: {0}", e.Address); + + caretaker.Revert(e); + + Console.WriteLine("Second reverted Address: {0}", e.Address); + + } + + } +} diff --git a/src/MememntoPattern/EmployeeSerialized/LimitedSizeStack.cs b/src/MememntoPattern/EmployeeSerialized/LimitedSizeStack.cs new file mode 100644 index 0000000..c34af1f --- /dev/null +++ b/src/MememntoPattern/EmployeeSerialized/LimitedSizeStack.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace MememntoPattern.EmployeeSerialized +{ + public class LimitedSizeStack : LinkedList + { + private readonly int maxSize; + public LimitedSizeStack(int maxSize) + { + this.maxSize = maxSize; + } + + public void Push(T item) + { + AddFirst(item); + + if (Count > maxSize) + RemoveLast(); + } + + public T Pop() + { + var item = First.Value; + RemoveFirst(); + return item; + } + } +} diff --git a/src/MememntoPattern/MementoPatternExamples.cs b/src/MememntoPattern/MementoPatternExamples.cs index fb49ae5..3c64def 100644 --- a/src/MememntoPattern/MementoPatternExamples.cs +++ b/src/MememntoPattern/MementoPatternExamples.cs @@ -1,4 +1,5 @@ using MememntoPattern.Employee; +using MememntoPattern.EmployeeSerialized; using System; using System.Collections.Generic; using System.Linq; @@ -25,6 +26,15 @@ namespace MememntoPattern EmployeeExample empExample = new EmployeeExample(); empExample.Run(); + + GoToNextStep(); + + EmployeeSerializedExample empSerExample = new EmployeeSerializedExample(); + empSerExample.Run(); + + GoToNextStep(); + + Console.WriteLine(GetPitfalls()); } string GetWhenToUse() @@ -51,6 +61,14 @@ Caretaker: keeps the mementos Memento: (Magic cookie) internal state of the object"; } + string GetPitfalls() + { + return @" +Can be expensive +Deltes/history +Exposing information only to memento so that we don't brake encapsulation"; + } + private static void GoToNextStep() { Console.ReadKey(); diff --git a/src/MememntoPattern/project.json b/src/MememntoPattern/project.json index 2402f0c..6a306c8 100644 --- a/src/MememntoPattern/project.json +++ b/src/MememntoPattern/project.json @@ -3,7 +3,8 @@ "dependencies": { "NETStandard.Library": "1.5.0-rc2-24027", - "Newtonsoft.Json": "8.0.3" + "Newtonsoft.Json": "8.0.3", + "System.Runtime.Serialization.Primitives": "4.0.10-*" }, "frameworks": {