🧠Memento Pattern – Preserving Object State Without Breaking Encapsulation
The Memento Pattern is a behavioral design pattern that lets you capture and store an object's internal state without exposing its internals—so you can restore it later. It’s especially useful when implementing features like undo/redo.
📌 Real-World Analogy
Think of the Undo feature in a text editor. Every time you type, the editor saves a snapshot (memento) of your content. When you click Undo, it rolls back to a previous state—without the editor knowing how the text is internally managed.
Another analogy is saving a game: when you hit "save," the game stores your progress as a memento. If you make a mistake or want to try a different path, you can load the saved state and continue from there, without the game engine exposing all its internal variables or logic.
In both cases, the key idea is that the caretaker (the editor or game menu) manages these snapshots, but never inspects or modifies their contents. This preserves encapsulation and keeps the internal workings of the object safe from outside interference.
đź§© When to Use
- You need to implement Undo/Redo
- You want to save checkpoints or restore object state
- You must preserve encapsulation of the object
đź’ˇ Structure Overview
- Originator – The object whose state needs saving
- Memento – A snapshot object holding state
- Caretaker – Manages mementos without inspecting them
đź”§ Code Example
// Memento
class EditorMemento {
public string Content { get; }
public EditorMemento(string content) => Content = content;
}
// Originator
class TextEditor {
public string Content { get; set; }
public EditorMemento Save() => new EditorMemento(Content);
public void Restore(EditorMemento memento) => Content = memento.Content;
}
// Caretaker
class History {
private Stack<EditorMemento> history = new();
public void Push(EditorMemento m) => history.Push(m);
public EditorMemento Pop() => history.Pop();
}
# Memento
class EditorMemento:
def __init__(self, content):
self._content = content
def get_content(self):
return self._content
# Originator
class TextEditor:
def __init__(self):
self.content = ""
def save(self):
return EditorMemento(self.content)
def restore(self, memento):
self.content = memento.get_content()
# Caretaker
class History:
def __init__(self):
self._history = []
def push(self, memento):
self._history.append(memento)
def pop(self):
return self._history.pop()
✅ Pros and ❌ Cons
Pros | Cons |
---|---|
Preserves encapsulation – internal state is saved/restored without exposing object internals | Can lead to memory overhead – storing many mementos may consume significant resources |
Enables undo/redo features – makes it easy to implement user-friendly history functionality | Requires careful state management – improper use can result in inconsistent or invalid states |
Easy to implement – straightforward structure with clear roles (Originator, Memento, Caretaker) | May be complex for large objects – deep copying or serializing complex state can be challenging |
Improves reliability – allows safe rollback to previous states in case of errors | Potential security risk – sensitive data may be stored in mementos if not handled properly |
Decouples state management – Caretaker manages history without knowing state details | Not suitable for all scenarios – may not be efficient for frequently changing or very large states |
đź—‚ UML Diagram
classDiagram
class Originator {
-state: string
+save(): Memento
+restore(m: Memento)
}
class Memento {
-state: string
+getState(): string
}
class Caretaker {
-mementos: Stack<Memento>
+push(m: Memento)
+pop(): Memento
}
Originator --> Memento
Caretaker --> Memento
Real-World Use Cases
-
IDE Undo/Redo (e.g., Visual Studio, Notepad++)
Every edit operation creates a memento of the document’s state, enabling users to undo or redo changes seamlessly. -
Game state snapshotting
Games often save checkpoints or allow players to save/load progress. Each save is a memento capturing the game’s state at that moment. -
Database restore points
Databases can create restore points or backups (mementos) to roll back to a previous state in case of errors or data corruption. -
Graphic editors
Applications like Photoshop use mementos to let users revert to previous versions of an image after a series of edits. -
Form input history
Web forms or wizards can use mementos to let users move back and forth between steps without losing entered data.
đź§ Test your Understnainding
🔚 Conclusion
The Memento Pattern is a simple yet powerful tool when you need to preserve state while keeping object internals private. It helps bring reliability and user-friendly features like undo/redo into your applications without violating encapsulation.