Memento design pattern
Memento design pattern is a behavioral pattern that lets you save and restore an object’s previous state without breaking its encapsulation, acting like a “snapshot” or “checkpoint” for undo/redo functionality, game saves, or versioning. It involves three key players: the Originator (creates and saves the state), the Memento (holds the state data), and the Caretaker (manages the Mementos, deciding when to save or restore).
Key Components
- Originator: The object whose state needs to be saved (e.g., a text editor). It creates a Memento to store its internal state and can restore itself from a Memento.
- Memento: An object that stores the Originator’s state. It acts like a read-only “lockbox” that the Caretaker holds, protecting the Originator’s private data.
- Caretaker: Manages the Mementos (e.g., the undo history stack). It requests the Originator to save its state and later asks it to restore from a specific Memento, but doesn’t look inside the Memento.
// memento
class TextMemento {
private final String text;
public TextMemento(String text) {
this.text = text;
}
public String getText() {
return text;
}
}
// origniator
class TextEditor {
private String text;
public void type(String newText) {
text = (text == null ? "" : text) + newText;
}
public String getText() {
return text;
}
// Save current state
public TextMemento save() {
return new TextMemento(text);
}
// Restore previous state
public void restore(TextMemento memento) {
this.text = memento.getText();
}
}
// caretaker
import java.util.Stack;
class UndoManager {
private Stack<TextMemento> history = new Stack<>();
public void save(TextEditor editor) {
history.push(editor.save());
}
public void undo(TextEditor editor) {
if (!history.isEmpty()) {
TextMemento memento = history.pop();
editor.restore(memento);
} else {
System.out.println("Nothing to undo!");
}
}
}
// client
public class MementoDemo {
public static void main(String[] args) {
TextEditor editor = new TextEditor();
UndoManager undoManager = new UndoManager();
editor.type("Hello ");
undoManager.save(editor);
editor.type("World!");
undoManager.save(editor);
editor.type(" Welcome to Java.");
System.out.println("Current: " + editor.getText());
// Undo last action
undoManager.undo(editor);
System.out.println("After Undo 1: " + editor.getText());
// Undo again
undoManager.undo(editor);
System.out.println("After Undo 2: " + editor.getText());
}
}
How It Works (Undo Example)
- User Action: The user types in a text editor (Originator).
- Save State: Before the action, the Caretaker (e.g., an UndoManager) asks the Originator to save its current state into a Memento.
- Store Memento: The Originator creates a Memento (snapshot) of its text and returns it to the Caretaker, which stores it (e.g., on a stack).
- Restore (Undo): If the user hits “undo,” the Caretaker retrieves the last Memento and tells the Originator to restore its state from it.
Get Kaizen Chandra’s stories in your inbox
Join Medium for free to get updates from this writer.
Common Use Cases
- Undo/Redo: Text editors, drawing programs.
- Checkpoints: Saving game progress.
- Transactions: Reverting database changes.
- Versioning: Creating history of document changes.
Benefits
- Encapsulation: Preserves the Originator’s internal structure by isolating its state in the Memento.
- Flexibility: Allows complex state management (like undo/redo) without tightly coupling the Caretaker to the Originator’s internals.










