Last Updated: February 24, 2026
The Memento Design Pattern is a behavioral design pattern that lets you capture and store an object’s internal state so it can be restored later, without violating encapsulation.
It’s particularly useful in situations where:
Let’s walk through a real-world example to see how we can apply the Memento Pattern to solve a problem that involves implementing undo functionality in a text editor.
Imagine you’re building a simple text editor. The editor supports basic operations like:
type(String text) – appends text to the current documentgetContent() – returns the current document textundo() – reverts to the previous version of the contentImplementing typing and reading is easy. The real challenge is undo.
The most straightforward approach is to have the client manually capture the editor's state before each operation and feed it back during undo:
The client is doing all the heavy lifting: fetching internal state, storing it, and feeding it back during undo.
Here is how the client uses it:
While this naive implementation works for very basic undo logic, it introduces several major issues:
The client must call getContent() to fetch internal state and pass it directly to undo(). This means the client knows that the editor's state is a string called "content."
If the editor later adds cursor position, selection range, or formatting metadata, the client must be updated to snapshot all of those too. The editor's internal structure has leaked into every class that implements undo.
The client must remember to take a snapshot before every operation. Miss one, and you have a gap in your undo history. This is manual, error-prone, and scatters undo logic across the entire codebase instead of centralizing it.
What if the editor's state grows to include cursor position, selection range, font formatting, and scroll position? The client would need to capture all of those fields separately, store them in some custom structure, and feed them all back during undo. The snapshot logic balloons in complexity, and it is all in the wrong place, outside the editor instead of inside it.
The same code that handles user interactions is also managing state snapshots. This violates the single responsibility principle and makes both the UI code and the undo logic harder to test, maintain, and extend.
We need a design that:
This is exactly what the Memento pattern provides.
The Memento Design Pattern allows an object to save and restore its state without exposing its internal structure. It achieves this by encapsulating the state in a special object called a Memento.
Two characteristics define the Memento pattern:
Memento has three participants.
TextEditor)The object whose internal state you want to capture and restore.
The originator is the only participant that touches its own private fields. It packages them into a memento during save, and unpacks them during restore. No other object needs to know what those fields are or how they are structured.
TextEditorMemento)An immutable snapshot of the originator's state at a specific point in time. Store the originator's state in a way that prevents external modification
UndoManager)The external object that decides when to save and restore state. It manages the lifecycle of mementos. It never examines or modifies the content of a memento, it just treats it as a black box.
Here is the Memento workflow step by step:
Before the user performs an operation (like typing, deleting, or formatting), the caretaker asks the originator to save its current state.
The originator reads its own private fields, packages them into a new memento object, and returns it to the caretaker.
The caretaker pushes the memento onto a history stack (or list). It does not open the memento or read its contents.
The originator's state changes through normal operations (typing text, moving shapes, etc.).
The caretaker pops the most recent memento from the history stack and passes it to the originator.
The originator reads the state from the memento and overwrites its current fields. The object is now back to exactly how it was when the memento was created.
Let’s refactor our naive text editor into a clean, maintainable design using the Memento Pattern. We will create the memento, then the originator, then the caretaker, and finally wire them together in client code.
The memento stores a snapshot of the TextEditor's internal state. It has three important properties:
private final (or readonly) and cannot be changed after creationThis class is passive. It does not contain any logic, just a frozen snapshot of the editor's state at the moment it was created.
TextEditorThe originator is the object whose state we want to save and restore. It provides two key methods beyond its normal operations:
save() — creates a memento capturing the current staterestore(memento) — replaces the current state with the state from the mementoNotice that the save() and restore() methods are the only ones that interact with the memento. The rest of the editor (typing, getting content) works exactly as before. The memento pattern adds state capture without changing how the object normally operates.
The caretaker manages the history of mementos. It is responsible for:
The TextEditorUndoManager allows undo operations without the client managing snapshots directly. Notice that save() and undo() take a TextEditor reference but never call getContent() or any other method that exposes internal state. They only call save() and restore(), which return and accept opaque mementos.
Now let's put it all together. The client creates an editor and an undo manager, performs operations, saves state at appropriate moments, and undoes when needed.
TextEditor handles state, and the TextEditorUndoManager handles historyWhat happens when the product manager says "We need to restore cursor position too, not just content"? With the naive approach, this would be a nightmare. The client would need to capture two fields instead of one, store them in some tuple or object, and know about both when undoing.
With Memento, the change is entirely inside the originator.
The undo manager did not change at all. Neither did the client code. The only files that changed were the memento and the editor. This is the Open/Closed Principle at work. You extended the system's capability (restoring cursor position) by modifying only the originator and its memento, without touching any external code.
If you later add selection range, scroll position, or font formatting, the same principle applies. The memento and editor grow, but the undo manager and client remain untouched.