using System; namespaceMementoPatternDemo { // The Originator holds some important state that may change over time. It // also defines a method for saving the state inside a memento and another // method for restoring the state from it. classOriginator { // For the sake of simplicity, the originator's state is stored inside a // single variable. privatestring _state;
publicOriginator(string state) { this._state = state; Console.WriteLine("Originator: My initial state is: " + state); }
// The Originator's business logic may affect its internal state. // Therefore, the client should backup the state before launching // methods of the business logic via the save() method. publicvoidDoSomething() { Console.WriteLine("Originator: I'm doing something important."); this._state = this.GenerateRandomString(30); Console.WriteLine($"Originator: and my state has changed to: {_state}"); }
while (length > 0) { result += allowedSymbols[new Random().Next(0, allowedSymbols.Length)];
Thread.Sleep(12);
length--; }
return result; }
// Saves the current state inside a memento. public IMemento Save() { returnnew ConcreteMemento(this._state); }
// Restores the Originator's state from a memento object. publicvoidRestore(IMemento memento) { if (!(memento is ConcreteMemento)) { thrownew Exception("Unknown memento class " + memento.ToString()); }
this._state = memento.GetState(); Console.Write($"Originator: My state has changed to: {_state}"); } }
// The Memento interface provides a way to retrieve the memento's metadata, // such as creation date or name. However, it doesn't expose the // Originator's state. publicinterfaceIMemento { stringGetName();
stringGetState();
DateTime GetDate(); }
// The Concrete Memento contains the infrastructure for storing the // Originator's state. classConcreteMemento : IMemento { privatestring _state;
// The Originator uses this method when restoring its state. publicstringGetState() { returnthis._state; }
// The rest of the methods are used by the Caretaker to display // metadata. publicstringGetName() { return$"{this._date} / ({this._state.Substring(0, 9)})..."; }
public DateTime GetDate() { returnthis._date; } }
// The Caretaker doesn't depend on the Concrete Memento class. Therefore, it // doesn't have access to the originator's state, stored inside the memento. // It works with all mementos via the base Memento interface. classCaretaker { privateList<IMemento> _mementos = new List<IMemento>();
Console.WriteLine("\n\nClient: Once more!\n"); caretaker.Undo();
Console.WriteLine(); // output
// Originator: My initial state is: Super-duper-super-puper-super.
// Caretaker: Saving Originator's state... // Originator: I'm doing something important. // Originator: and my state has changed to: oGyQIIatlDDWNgYYqJATTmdwnnGZQj
// Caretaker: Saving Originator's state... // Originator: I'm doing something important. // Originator: and my state has changed to: jBtMDDWogzzRJbTTmEwOOhZrjjBULe
// Caretaker: Saving Originator's state... // Originator: I'm doing something important. // Originator: and my state has changed to: exoHyyRkbuuNEXOhhArKccUmexPPHZ
// Caretaker: Here's the list of mementos: // 12.06.2018 15:52:45 / (Super-dup...) // 12.06.2018 15:52:46 / (oGyQIIatl...) // 12.06.2018 15:52:46 / (jBtMDDWog...)
// Client: Now, let's rollback!
// Caretaker: Restoring state to: 12.06.2018 15:52:46 / (jBtMDDWog...) // Originator: My state has changed to: jBtMDDWogzzRJbTTmEwOOhZrjjBULe
// Client: Once more!
// Caretaker: Restoring state to: 12.06.2018 15:52:46 / (oGyQIIatl...) // Originator: My state has changed to: oGyQIIatlDDWNgYYqJATTmdwnnGZQj } } }