mirror of
https://github.com/farcasclaudiu/design_pattens.git
synced 2026-06-22 07:01:29 +03:00
memento design pattern
This commit is contained in:
+3
-1
@@ -18,6 +18,7 @@ using design_patterns.behavioral.chainofresponsability;
|
|||||||
using design_patterns.behavioral.command;
|
using design_patterns.behavioral.command;
|
||||||
using design_patterns.behavioral.iterator;
|
using design_patterns.behavioral.iterator;
|
||||||
using design_patterns.behavioral.mediator;
|
using design_patterns.behavioral.mediator;
|
||||||
|
using design_patterns.behavioral.memento;
|
||||||
|
|
||||||
namespace design_patterns
|
namespace design_patterns
|
||||||
{
|
{
|
||||||
@@ -49,7 +50,8 @@ namespace design_patterns
|
|||||||
// await ChainOfResponsabilitySample.Run();
|
// await ChainOfResponsabilitySample.Run();
|
||||||
// await CommandSample.Run();
|
// await CommandSample.Run();
|
||||||
// await IteratorSample.Run();
|
// await IteratorSample.Run();
|
||||||
await MediatorSample.Run();
|
// await MediatorSample.Run();
|
||||||
|
await MementoSample.Run();
|
||||||
}
|
}
|
||||||
catch (System.Exception ex)
|
catch (System.Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,136 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using System.Text;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace design_patterns.behavioral.memento
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Memento is a behavioral design pattern that lets you
|
||||||
|
/// save and restore the previous state of an object
|
||||||
|
/// without revealing the details of its implementation.
|
||||||
|
///
|
||||||
|
/// Use it when:
|
||||||
|
/// - you want to produce snapshots of the object’s state
|
||||||
|
/// to be able to restore a previous state of the object.
|
||||||
|
/// - direct access to the object’s fields/getters/setters
|
||||||
|
/// violates its encapsulation.
|
||||||
|
/// </summary>
|
||||||
|
public class MementoSample
|
||||||
|
{
|
||||||
|
public static async Task Run()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Behavioral - Memento");
|
||||||
|
|
||||||
|
var board = new DrawingBoard();
|
||||||
|
System.Console.WriteLine(board);
|
||||||
|
// init state
|
||||||
|
var memento0 = board.Save();
|
||||||
|
|
||||||
|
board.DrawLine(new Line(0,0, 10, 20, 1, "red"));
|
||||||
|
board.DrawLine(new Line(10,5, 15, 25, 2, "green"));
|
||||||
|
|
||||||
|
System.Console.WriteLine(board);
|
||||||
|
var memento1 = board.Save();
|
||||||
|
|
||||||
|
board.DrawLine(new Line(20,20, 5, 20, 1, "blue"));
|
||||||
|
|
||||||
|
System.Console.WriteLine(board);
|
||||||
|
var memento2 = board.Save();
|
||||||
|
|
||||||
|
board.DrawLine(new Line(7, 7, 7, 7, 3, "new red"));
|
||||||
|
System.Console.WriteLine(board);
|
||||||
|
var memento3 = board.Save();
|
||||||
|
|
||||||
|
#if false
|
||||||
|
// only memento
|
||||||
|
System.Console.WriteLine("Restore memento1");
|
||||||
|
board.Restore(memento1);
|
||||||
|
System.Console.WriteLine(board);
|
||||||
|
#else
|
||||||
|
// memento with undo()
|
||||||
|
System.Console.WriteLine("Undo one step");
|
||||||
|
board.Undo();
|
||||||
|
System.Console.WriteLine(board);
|
||||||
|
|
||||||
|
System.Console.WriteLine("Undo one more step");
|
||||||
|
board.Undo();
|
||||||
|
System.Console.WriteLine(board);
|
||||||
|
|
||||||
|
System.Console.WriteLine("Undo one more more step");
|
||||||
|
board.Undo();
|
||||||
|
System.Console.WriteLine(board);
|
||||||
|
System.Console.WriteLine("Undo one more more more step");
|
||||||
|
board.Undo();
|
||||||
|
System.Console.WriteLine(board);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// keeps the snapshot of the system/component
|
||||||
|
/// </summary>
|
||||||
|
public class Memento {
|
||||||
|
|
||||||
|
public List<Line> Lines { get; set; } = new List<Line>();
|
||||||
|
|
||||||
|
public Memento(DrawingBoard board)
|
||||||
|
{
|
||||||
|
// copy inner Lines and NOT the list reference
|
||||||
|
this.Lines.AddRange(board.Lines);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DrawingBoard {
|
||||||
|
public List<Line> Lines { get; set; } = new List<Line>();
|
||||||
|
private Stack<Memento> _history = new Stack<Memento>();
|
||||||
|
|
||||||
|
public void DrawLine(Line line)
|
||||||
|
{
|
||||||
|
Lines.Add(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.AppendLine($"Board contains: {this.Lines.Count} lines ->");
|
||||||
|
foreach (var line in Lines)
|
||||||
|
{
|
||||||
|
sb.AppendLine($"Line: from {line.fromX}-{line.fromY} to {line.toX}-{line.toY} width {line.width} color {line.color}");
|
||||||
|
}
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Memento Save()
|
||||||
|
{
|
||||||
|
var memento = new Memento(this);
|
||||||
|
_history.Push(memento);
|
||||||
|
return memento;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Restore(Memento memento)
|
||||||
|
{
|
||||||
|
if (memento != null &&
|
||||||
|
_history.Contains(memento)) {
|
||||||
|
while(!_history.Peek().Equals(memento)) {
|
||||||
|
_history.Pop();
|
||||||
|
}
|
||||||
|
this.Lines = memento.Lines;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Undo() {
|
||||||
|
if(_history.Count>1){
|
||||||
|
_history.Pop();
|
||||||
|
var memento = _history.Peek();
|
||||||
|
Restore(memento);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record Line(int fromX, int fromY,
|
||||||
|
int toX, int toY,
|
||||||
|
int width, string color);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user