Design Pattern 22: Memento Pattern - Complete Guide with Undo/Redo Examples
π Download the complete Design Pattern series code from our design_pattern repository.
π― What is the Memento Pattern?
The Memento Pattern is a behavioral design pattern that allows you to capture and restore an objectβs state without exposing its internal structure. Itβs widely used for implementing undo/redo, state recovery, and history management in applications.
Key Benefits:
- β State recovery - Restore previous states easily
- β Encapsulation - Internal state is hidden from external objects
- β Undo/redo support - Implement robust history features
- β Maintainability - Clean separation of concerns
- β Extensibility - Add new state types easily
π Real-World Problem: Text Editor Undo/Redo
Suppose you are building a text editor with the following requirements:
- Users can input text and undo changes (Ctrl+Z)
- The system must save history for recovery
- The client should not know the details of state management
Business Rules:
- All state changes are managed by a caretaker
- The originator creates and restores mementos
- The client interacts only with simple undo/redo operations
ποΈ Object-Oriented Analysis (OOA)

Identified Forces:
- Data loss risk - No way to recover previous states
- High coupling - Client must manage state logic
- Hard to extend - Adding new state types is difficult
π‘ Memento Pattern Solution
By introducing the Memento Pattern, we can capture and restore object states without exposing internal details.

Memento Pattern Components:
- Originator - Creates and restores state
- Memento - Stores state
- Caretaker - Manages history and recovery
π οΈ Implementation: Text Editor Undo/Redo

1. Originator
class TextEditor {
private var text: String = ""
fun type(newText: String) { text += newText }
fun getText(): String = text
fun save(): Memento = Memento(text)
fun restore(memento: Memento) { text = memento.getText() }
data class Memento(private val state: String) { fun getText(): String = state }
}
2. Caretaker
class History {
private val mementos = mutableListOf<TextEditor.Memento>()
fun save(memento: TextEditor.Memento) { mementos.add(memento) }
fun undo(): TextEditor.Memento? = if (mementos.isNotEmpty()) mementos.removeAt(mementos.size - 1) else null
}
3. Client Code
fun main() {
val textEditor = TextEditor()
val history = History()
textEditor.type("Hello")
history.save(textEditor.save())
textEditor.type(", World")
history.save(textEditor.save())
textEditor.type("! This is Memento Pattern.")
println("Current Text: ${textEditor.getText()}")
textEditor.restore(history.undo()!!)
println("Undo Text: ${textEditor.getText()}")
textEditor.restore(history.undo()!!)
println("Undo Text: ${textEditor.getText()}")
}
Expected Output:
Current Text: Hello, World! This is Memento Pattern.
Undo Text: Hello, World!
Undo Text: Hello
π Memento Pattern vs Alternative Approaches
Approach | Pros | Cons |
---|---|---|
Memento Pattern | β
Encapsulated state β Undo/redo support | β Memory usage for large histories β Caretaker complexity |
Direct State Management | β Simple for small apps | β High coupling β No encapsulation |
Event Sourcing | β
Full history β Auditing | β Complex implementation β Storage overhead |
π― When to Use the Memento Pattern
β Perfect For:
- Text editors (undo/redo)
- Game save systems
- Workflow engines (rollback)
- Configuration management
- Stateful UI components
β Avoid When:
- Large, complex states (memory overhead)
- Simple, stateless systems
π§ Advanced Memento Pattern Implementations
- Multi-level undo/redo
- State compression for memory optimization
- Versioning and branching
- Persistent storage of mementos
π Real-World Applications
- Text editors (VSCode, Word)
- Drawing and design tools (undo/redo)
- Game save/load systems
- Database transaction rollback
π¨ Common Pitfalls and Best Practices
- Avoid storing large objects in mementos
- Use immutable mementos for safety
- Document state transitions clearly
π Related Articles
- Design Pattern 1: Object-Oriented Concepts
- Design Pattern 2: Design Principles
- Command Pattern
- State Pattern
- Observer Pattern
β Conclusion
Through the Memento Pattern, we successfully implemented robust undo/redo and state recovery features, making the system more reliable and user-friendly.
Key Advantages:
- π― State recovery
- π§ Encapsulation
- π Undo/redo support
- π‘οΈ Maintainability
- β‘ Extensibility
Design Principles Followed:
- Single Responsibility Principle (SRP): State management is separated
- Open-Closed Principle (OCP): Add new state types easily
- Donβt Repeat Yourself (DRY): Centralize state logic
Perfect For:
- Text editors
- Game save systems
- Workflow engines
The Memento Pattern provides an elegant solution for state recovery and undo/redo in modern applications!
π‘ Pro Tip: Use immutable mementos and avoid storing large objects to optimize performance.
π Stay Updated: Follow our Design Pattern series for more software architecture insights!
Enjoy Reading This Article?
Here are some more articles you might like to read next: