Role
This pattern is used to capture an object’s internal state and save it externally so that it can be restored later.
Design

Implementation
- Client -> TestMementoPattern
- Originator -> ItemsManager
- Memento -> Memento
- Caretaker -> Storage
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace MementoPattern
{
public class TestMementoPattern
{
public static void Main(string[] args)
{
Console.WriteLine("APPLICATION START \n\n");
var storage = new Storage();
var manager = new ItemsManager();
var itemsGenerator = new ItemsGenerator();
Console.WriteLine("######################################");
manager.Operation(itemsGenerator[1]);
manager.Operation(itemsGenerator[0]);
manager.Operation(itemsGenerator[3]);
manager.Operation(itemsGenerator[2]);
Console.WriteLine("######################################");
storage.Memento = manager.Save();
manager.DisplayOperations();
Console.WriteLine("######################################");
manager.Operation(itemsGenerator[0]);
manager.Operation(itemsGenerator[0]);
manager.Operation(itemsGenerator[1]);
Console.WriteLine("######################################");
manager.DisplayOperations();
manager.Restore(storage.Memento);
manager.DisplayOperations();
Console.WriteLine("######################################");
manager.Operation(itemsGenerator[4]);
manager.Operation(itemsGenerator[5]);
Console.WriteLine("######################################");
manager.DisplayOperations();
}
}
public class Storage
{
public Memento Memento { get; set; }
}
public class ItemsGenerator
{
private readonly Item[] _items = {
new Item("First", 1),
new Item("Second", 2),
new Item("Third", 3),
new Item("Fourth", 4),
new Item("Fifth", 5),
new Item("Sixth", 6),
};
public Item this[int index]
{
get { return this._items[index]; }
}
}
[Serializable]
public class ItemsManager
{
private List<Item> _items;
public ItemsManager()
{
this._items = new List<Item>();
}
public void Operation(Item item)
{
this._items.Add(item);
Console.WriteLine("\t\tOperations {0} is executed", item);
}
public Memento Save()
{
Console.WriteLine("\n\nSAVE\n");
var memento = new Memento();
return memento.Save(this._items);
}
public void Restore(Memento memento)
{
Console.WriteLine("\n\nRESTORE\n");
this._items = (List<Item>) memento.Restore();
}
public void DisplayOperations()
{
Console.WriteLine("======================================");
Console.WriteLine("MANAGER - actual executed operations:\n");
foreach (Item item in this._items)
{
Console.WriteLine(item);
}
Console.WriteLine("======================================");
}
}
[Serializable]
public class Memento
{
private readonly BinaryFormatter _binaryFormatter;
private readonly MemoryStream _memoryStream;
public Memento()
{
this._memoryStream = new MemoryStream();
this._binaryFormatter = new BinaryFormatter();
}
public Memento Save(object obj)
{
this._binaryFormatter.Serialize(this._memoryStream, obj);
return this;
}
public object Restore()
{
this._memoryStream.Seek(0, SeekOrigin.Begin);
object obj = this._binaryFormatter.Deserialize(this._memoryStream);
this._memoryStream.Close();
return obj;
}
}
[Serializable]
public class Item
{
public Item(string name, int value)
{
this.Value = value;
this.Name = name;
}
public int Value { get; private set; }
public string Name { get; private set; }
public override string ToString()
{
return String.Format("\t[Name = \"{0}\", \tValue = {1}]", this.Name, this.Value);
}
}
}
OUTPUT:
APPLICATION START######################################
Operations [Name = "Second", Value = 2] is executed
Operations [Name = "First", Value = 1] is executed
Operations [Name = "Fourth", Value = 4] is executed
Operations [Name = "Third", Value = 3] is executed
######################################
SAVE
======================================
MANAGER – actual executed operations:
[Name = "Second", Value = 2]
[Name = "First", Value = 1]
[Name = "Fourth", Value = 4]
[Name = "Third", Value = 3]
======================================
######################################
Operations [Name = "First", Value = 1] is executed
Operations [Name = "First", Value = 1] is executed
Operations [Name = "Second", Value = 2] is executed
######################################
======================================
MANAGER – actual executed operations:
[Name = "Second", Value = 2]
[Name = "First", Value = 1]
[Name = "Fourth", Value = 4]
[Name = "Third", Value = 3]
[Name = "First", Value = 1]
[Name = "First", Value = 1]
[Name = "Second", Value = 2]
======================================
RESTORE
======================================
MANAGER – actual executed operations:
[Name = "Second", Value = 2]
[Name = "First", Value = 1]
[Name = "Fourth", Value = 4]
[Name = "Third", Value = 3]
======================================
######################################
Operations [Name = "Fifth", Value = 5] is executed
Operations [Name = "Sixth", Value = 6] is executed
######################################
======================================
MANAGER – actual executed operations:
[Name = "Second", Value = 2]
[Name = "First", Value = 1]
[Name = "Fourth", Value = 4]
[Name = "Third", Value = 3]
[Name = "Fifth", Value = 5]
[Name = "Sixth", Value = 6]
======================================
Use when
- An object’s state must be saved to be restored later, and
- It is undesirable to expose the state directly.
Bibliography
- Erich Gamma et al. Design Patterns
- C# Design Patterns



