using System.Collections.Generic;
namespace RefactoringGuru.DesignPatterns.Memento.Conceptual
public Originator(string state)
Console.WriteLine("Originator: My initial state is: " + state);
public void DoSomething()
Console.WriteLine("Originator: I'm doing something important.");
this._state = this.GenerateRandomString(30);
Console.WriteLine($"Originator: and my state has changed to: {_state}");
private string GenerateRandomString(int length = 10)
string allowedSymbols = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
string result = string.Empty;
result += allowedSymbols[new Random().Next(0, allowedSymbols.Length)];
return new ConcreteMemento(this._state);
public void Restore(IMemento memento)
if (!(memento is ConcreteMemento))
throw new Exception("Unknown memento class " + memento.ToString());
this._state = memento.GetState();
Console.Write($"Originator: My state has changed to: {_state}");
public interface IMemento
class ConcreteMemento : IMemento
public ConcreteMemento(string state)
this._date = DateTime.Now;
return $"{this._date} / ({this._state.Substring(0, 9)})...";
public DateTime GetDate()
private List<IMemento> _mementos = new List<IMemento>();
private Originator _originator = null;
public Caretaker(Originator originator)
this._originator = originator;
Console.WriteLine("\nCaretaker: Saving Originator's state...");
this._mementos.Add(this._originator.Save());
if (this._mementos.Count == 0)
var memento = this._mementos.Last();
this._mementos.Remove(memento);
Console.WriteLine("Caretaker: Restoring state to: " + memento.GetName());
this._originator.Restore(memento);
public void ShowHistory()
Console.WriteLine("Caretaker: Here's the list of mementos:");
foreach (var memento in this._mementos)
Console.WriteLine(memento.GetName());
static void Main(string[] args)
Originator originator = new Originator("Super-duper-super-puper-super.");
Caretaker caretaker = new Caretaker(originator);
originator.DoSomething();
originator.DoSomething();
originator.DoSomething();
Console.WriteLine("\nClient: Now, let's rollback!\n");
Console.WriteLine("\n\nClient: Once more!\n");