Objective 🎯
Allow to save and restore a previous state of an object without violating encapsulation (not revealing details of its implementation).
Type ✅
✔️Behavioral: Describes how objects interact/communicate between themselves.
❌Creational: Describes how to instantiate an object without large and complex.
❌Structural: Describes how objects/classes are composed to form larger structures.
UML 📐
Participants 🔗
• Memento:
- Stores the internal state of the Originator object
• Originator:
- Creates a memento object containing a snapshot of its current internal state
- Uses memento to restore its internal state
• Caretaker:
- Responsible for the memento’s safekeeping
Sample Code 🎮
Structural Example 🏛️
public static class MementoStructural
{
public static void Execute()
{
Originator lOriginator = new Originator();
lOriginator.State = "On";
// Store internal state
Caretaker lCaretaker = new Caretaker();
lCaretaker._Memento = lOriginator.CreateMemento();
// Continue changing originator
lOriginator.State = "Off";
// Restore saved state
lOriginator.SetMemento(lCaretaker._Memento);
}
}
public class Originator
{
private string _State;
public string State
{
get { return _State; }
set
{
Console.WriteLine($"Originator - Changing state from \"{_State}\" to \"{value}\"");
_State = value;
}
}
public Memento CreateMemento()
{
Console.WriteLine($"Originator - Creating memento of the current state \"{_State}\"");
return (new Memento(_State));
}
public void SetMemento(Memento prMemento)
{
Console.WriteLine($"Originator - Restoring state...");
State = prMemento._State;
}
}
public class Memento
{
public string _State { get; set; }
public Memento(string prState)
{
_State = prState;
}
}
public class Caretaker
{
public Memento _Memento { get; set; }
}
Output
Real-world Example 🔥
public static class MementoPractical
{
public static void Execute()
{
WordDocument lWordDocument = new WordDocument();
DocumentCaretaker lDocumentCaretaker = new DocumentCaretaker();
lWordDocument.Content = "Content ABC";
lWordDocument.SaveContentState(lDocumentCaretaker);
lWordDocument.Content = "Content ABCDEFG";
lWordDocument.RevertToLastSave(lDocumentCaretaker);
lWordDocument.Content = "Content 123";
lWordDocument.RevertToLastSave(lDocumentCaretaker);
}
}
public class WordDocument
{
private string _Content;
public string Content
{
get { return _Content; }
set
{
Console.WriteLine($"WordDocument - Changing content from \"{_Content}\" to \"{value}\"");
_Content = value;
}
}
public void SaveContentState(DocumentCaretaker prDocumentCaretaker)
{
Console.WriteLine($"WordDocument - Saving current content");
prDocumentCaretaker._DocumentMemento = new DocumentMemento(Content);
}
public void RevertToLastSave(DocumentCaretaker prDocumentCaretaker)
{
Console.WriteLine($"WordDocument - Restoring state...");
Content = prDocumentCaretaker._DocumentMemento._Content;
}
}
public class DocumentMemento
{
public string _Content { get; set; }
public DocumentMemento(string _prContent)
{
_Content = _prContent;
}
}
public class DocumentCaretaker
{
public DocumentMemento _DocumentMemento { get; set; }
}
Output