Add another example of the memento pattern
This commit is contained in:
30
src/MememntoPattern/EmployeeSerialized/Caretaker.cs
Normal file
30
src/MememntoPattern/EmployeeSerialized/Caretaker.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MememntoPattern.EmployeeSerialized
|
||||
{
|
||||
/// <summary>
|
||||
/// Caretaker
|
||||
/// </summary>
|
||||
public class Caretaker
|
||||
{
|
||||
private LimitedSizeStack<EmployeeMemento> employeeHistory;
|
||||
|
||||
public Caretaker()
|
||||
{
|
||||
employeeHistory = new LimitedSizeStack<EmployeeMemento>(10);
|
||||
}
|
||||
|
||||
public void Save(Employee emp)
|
||||
{
|
||||
employeeHistory.Push(emp.Save());
|
||||
}
|
||||
|
||||
public void Revert(Employee emp)
|
||||
{
|
||||
emp.Revert(employeeHistory.Pop());
|
||||
}
|
||||
}
|
||||
}
|
||||
33
src/MememntoPattern/EmployeeSerialized/Employee.cs
Normal file
33
src/MememntoPattern/EmployeeSerialized/Employee.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MememntoPattern.EmployeeSerialized
|
||||
{
|
||||
/// <summary>
|
||||
/// Originator
|
||||
/// </summary>
|
||||
public class Employee
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Address { get; set; }
|
||||
|
||||
public List<string> Phones { get; set; }
|
||||
|
||||
public EmployeeMemento Save()
|
||||
{
|
||||
return new EmployeeMemento(JsonConvert.SerializeObject(this));
|
||||
}
|
||||
|
||||
public void Revert(EmployeeMemento memento)
|
||||
{
|
||||
Employee newEmployee = JsonConvert.DeserializeObject<Employee>(memento.SerializedEmployee);
|
||||
Name = newEmployee.Name;
|
||||
Address = newEmployee.Address;
|
||||
Phones = newEmployee.Phones;
|
||||
}
|
||||
}
|
||||
}
|
||||
20
src/MememntoPattern/EmployeeSerialized/EmployeeMemento.cs
Normal file
20
src/MememntoPattern/EmployeeSerialized/EmployeeMemento.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MememntoPattern.EmployeeSerialized
|
||||
{
|
||||
/// <summary>
|
||||
/// Memento object
|
||||
/// </summary>
|
||||
public class EmployeeMemento
|
||||
{
|
||||
public string SerializedEmployee;
|
||||
|
||||
public EmployeeMemento(string serializedEmployee)
|
||||
{
|
||||
SerializedEmployee = serializedEmployee;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
31
src/MememntoPattern/EmployeeSerialized/LimitedSizeStack.cs
Normal file
31
src/MememntoPattern/EmployeeSerialized/LimitedSizeStack.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MememntoPattern.EmployeeSerialized
|
||||
{
|
||||
public class LimitedSizeStack<T> : LinkedList<T>
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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": {
|
||||
|
||||
Reference in New Issue
Block a user