Bird
Raised Fist0
LLDsystem_design~15 mins

Memento pattern in LLD - Deep Dive

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Overview - Memento pattern
What is it?
The Memento pattern is a design technique that helps save and restore an object's state without exposing its internal details. It allows an object to capture its current state and store it externally so it can be returned to that state later. This is useful for undo operations or rollback features in software. The pattern keeps the saved state separate from the object itself to maintain encapsulation.
Why it matters
Without the Memento pattern, saving and restoring an object's state can lead to exposing sensitive internal data or tightly coupling components. This makes software harder to maintain and more error-prone. The pattern solves this by cleanly separating state storage from the object's logic, enabling features like undo, redo, and checkpoints that improve user experience and reliability.
Where it fits
Before learning the Memento pattern, you should understand basic object-oriented programming concepts like classes, objects, and encapsulation. After mastering it, you can explore related design patterns like Command for undo/redo operations and Prototype for cloning objects. It fits into the broader topic of behavioral design patterns that manage object interactions and state changes.
Mental Model
Core Idea
The Memento pattern lets an object save its state externally so it can be restored later without revealing its inner details.
Think of it like...
Imagine writing a letter and making a photocopy before making changes. If you don't like the changes, you can go back to the photocopy without showing anyone the original letter's secrets.
┌─────────────┐       ┌───────────────┐       ┌─────────────┐
│   Originator│──────▶│   Memento     │◀──────│   Caretaker │
│ (has state) │       │ (stores state)│       │(stores memento)
└─────────────┘       └───────────────┘       └─────────────┘
       │                     ▲                      │
       │ save state          │                      │
       │────────────────────▶│                      │
       │                     │                      │
       │ restore state       │                      │
       │◀────────────────────│                      │
Build-Up - 7 Steps
1
FoundationUnderstanding Object State
🤔
Concept: Objects have internal data called state that defines their current condition.
Every object in programming holds information inside it, like a person's profile with name, age, and address. This information is called the object's state. Changing the state changes how the object behaves or appears.
Result
You can identify what data an object holds and how it changes over time.
Understanding that objects have state is essential because the Memento pattern revolves around saving and restoring this state.
2
FoundationEncapsulation and Its Importance
🤔
Concept: Encapsulation hides an object's internal details to protect its integrity.
Encapsulation means keeping an object's data private and only allowing controlled access through methods. This prevents accidental or harmful changes from outside. For example, a bank account object hides its balance and only allows deposits or withdrawals through specific functions.
Result
You know why objects protect their data and how this affects saving state.
Recognizing encapsulation helps understand why saving state externally without breaking privacy is challenging.
3
IntermediateSaving State Without Breaking Encapsulation
🤔Before reading on: do you think saving an object's state requires exposing its private data? Commit to yes or no.
Concept: The Memento pattern saves state externally without revealing private details.
Instead of letting others peek inside an object, the object creates a separate snapshot called a memento. This memento holds the state but does not allow changes or access to internal details. The object can give this memento to a caretaker who stores it safely.
Result
State is saved securely, and the object's privacy remains intact.
Knowing that the object itself controls what state is saved prevents breaking encapsulation and keeps design clean.
4
IntermediateRole of Caretaker in Memento Pattern
🤔Before reading on: do you think the caretaker can modify the saved state? Commit to yes or no.
Concept: The caretaker stores mementos but does not change or understand their content.
The caretaker acts like a safe box holding the mementos. It keeps them safe and returns them when needed but never opens or changes them. This separation ensures that only the originator controls the state.
Result
State management is organized and secure, avoiding accidental corruption.
Understanding the caretaker's limited role clarifies responsibilities and prevents misuse of saved states.
5
IntermediateRestoring State from a Memento
🤔
Concept: The originator uses a memento to revert to a previous state.
When needed, the originator asks the caretaker for a saved memento and uses it to restore its state. This allows undoing changes or returning to a known good condition without exposing internal details.
Result
The object returns to a previous state safely and cleanly.
Knowing how restoration works completes the pattern's cycle and enables features like undo.
6
AdvancedImplementing Memento Pattern in Practice
🤔Before reading on: do you think the memento should be mutable or immutable? Commit to your answer.
Concept: Mementos are usually immutable to prevent accidental changes after saving.
In real systems, mementos are designed so their stored state cannot be changed once created. This immutability ensures that saved snapshots remain reliable. The originator creates new mementos for each save and discards old ones as needed.
Result
State snapshots are consistent and trustworthy over time.
Understanding immutability in mementos prevents bugs related to corrupted saved states.
7
ExpertMemory and Performance Considerations
🤔Before reading on: do you think saving every state change is always efficient? Commit to yes or no.
Concept: Saving many states can consume memory; strategies are needed to balance performance and functionality.
In complex systems, saving every change can use a lot of memory and slow down performance. Experts use techniques like saving only important states, compressing mementos, or limiting undo steps. Sometimes, combining Memento with Command pattern helps manage changes efficiently.
Result
Systems remain responsive and scalable while supporting undo features.
Knowing these trade-offs helps design practical, efficient applications using the Memento pattern.
Under the Hood
The originator object creates a memento object that captures its internal state data. This memento is a separate object that stores the state in a way that does not expose the originator's private fields. The caretaker holds references to these mementos but cannot modify them. When restoring, the originator extracts the saved state from the memento and updates itself accordingly. This separation preserves encapsulation and allows safe state rollback.
Why designed this way?
The pattern was designed to solve the problem of saving object state without breaking encapsulation. Alternatives like exposing getters for all internal data would violate privacy and increase coupling. By isolating state snapshots in mementos and restricting access, the design keeps objects independent and maintainable. This approach balances flexibility (undo/redo) with software design principles.
┌───────────────┐       ┌───────────────┐       ┌───────────────┐
│   Originator  │──────▶│   Memento     │◀──────│   Caretaker   │
│ - state data  │       │ - saved state │       │ - stores memento│
│ - createMemento│       │ (immutable)   │       │ (no access to  │
│ - restore()   │       │               │       │  internals)    │
└───────────────┘       └───────────────┘       └───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does the caretaker modify the saved state in a memento? Commit yes or no.
Common Belief:The caretaker can change the saved state to fix errors or update data.
Tap to reveal reality
Reality:The caretaker only stores and returns mementos without modifying them; only the originator can change its state.
Why it matters:If the caretaker modifies state, it breaks encapsulation and can cause inconsistent or corrupted object states.
Quick: Is the memento pattern only useful for undo features? Commit yes or no.
Common Belief:Memento is only for undo/redo functionality in applications.
Tap to reveal reality
Reality:While commonly used for undo, the pattern also supports checkpoints, rollback, and state versioning in various domains.
Why it matters:Limiting the pattern's use narrows design options and misses opportunities for robust state management.
Quick: Does the memento expose all internal details of the originator? Commit yes or no.
Common Belief:Mementos expose the full internal state of the originator to anyone holding them.
Tap to reveal reality
Reality:Mementos encapsulate state and expose only what the originator allows, preserving privacy.
Why it matters:Exposing internals leads to tight coupling and fragile designs that are hard to maintain.
Quick: Is saving every single state change always practical? Commit yes or no.
Common Belief:Saving every change as a memento is efficient and always recommended.
Tap to reveal reality
Reality:Saving every change can cause memory bloat and performance issues; selective saving or compression is often necessary.
Why it matters:Ignoring this leads to slow, resource-heavy applications that degrade user experience.
Expert Zone
1
Mementos should be immutable to guarantee the integrity of saved states over time.
2
The originator controls what part of its state is saved, allowing selective snapshotting to optimize memory.
3
Combining Memento with Command pattern enables more flexible undo/redo systems by tracking both state and actions.
When NOT to use
Avoid using Memento when the object's state is huge or changes very frequently without meaningful checkpoints; instead, consider event sourcing or state diffs. Also, if exposing internal state is acceptable, simpler serialization might suffice.
Production Patterns
In real systems, Memento is used in text editors for undo, games for save points, and databases for transaction rollbacks. Often, it is combined with version control or command patterns to manage complex state changes efficiently.
Connections
Command pattern
Often combined with Memento to implement undo/redo by tracking both actions and states.
Understanding Command helps see how actions and state snapshots work together for flexible rollback.
Snapshot backups in storage systems
Memento is a software design version of snapshot backups that save system states for recovery.
Knowing how storage snapshots work clarifies the practical value of saving states externally.
Memory checkpoints in video games
Games use checkpoints like mementos to restore player progress without revealing internal game engine details.
Recognizing this connection shows how design patterns map to real-world interactive experiences.
Common Pitfalls
#1Allowing the caretaker to modify the memento's state.
Wrong approach:class Caretaker { Memento memento; void changeState() { memento.state = "new state"; // wrong: modifies saved state } }
Correct approach:class Caretaker { private final Memento memento; Caretaker(Memento m) { this.memento = m; } Memento getMemento() { return memento; } // no methods to modify memento }
Root cause:Misunderstanding the caretaker's role leads to breaking encapsulation and corrupting saved states.
#2Saving entire object state including unnecessary data causing memory bloat.
Wrong approach:class Originator { State fullState; // includes large logs, caches Memento save() { return new Memento(fullState); } }
Correct approach:class Originator { ImportantState minimalState; Memento save() { return new Memento(minimalState); } }
Root cause:Not selecting relevant state to save causes inefficient memory use and performance issues.
#3Restoring state from an outdated or incompatible memento.
Wrong approach:originator.restore(oldMemento); // oldMemento from different version or corrupted
Correct approach:if (originator.canRestore(memento)) { originator.restore(memento); } else { // handle error or ignore }
Root cause:Ignoring versioning or compatibility leads to errors and unstable application behavior.
Key Takeaways
The Memento pattern enables saving and restoring an object's state without exposing its internal details, preserving encapsulation.
It separates responsibilities among originator (creates/restores state), memento (stores state), and caretaker (stores mementos safely).
Mementos are usually immutable snapshots to ensure saved states remain consistent and reliable.
Practical use requires balancing memory and performance by saving selective states and managing memento lifecycles.
Combining Memento with other patterns like Command enhances undo/redo capabilities in complex systems.

Practice

(1/5)
1. What is the main purpose of the Memento pattern in system design?
easy
A. To create multiple instances of an object efficiently
B. To convert one interface to another compatible interface
C. To manage concurrent access to shared resources
D. To save and restore an object's state without exposing its internal details

Solution

  1. Step 1: Understand the role of Memento pattern

    The Memento pattern is designed to capture and externalize an object's internal state so that it can be restored later without exposing the object's implementation details.
  2. Step 2: Compare with other design patterns

    Other options describe different patterns: A is about object creation (Factory), C is about synchronization (Mutex), D is about interface compatibility (Adapter).
  3. Final Answer:

    To save and restore an object's state without exposing its internal details -> Option D
  4. Quick Check:

    Memento = Save & Restore State [OK]
Hint: Memento = save state secretly, no details shown [OK]
Common Mistakes:
  • Confusing Memento with Factory or Adapter patterns
  • Thinking it manages concurrency
  • Assuming it changes object interfaces
2. Which of the following correctly represents the key components of the Memento pattern?
easy
A. Subject, Observer, ConcreteObserver
B. Originator, Memento, Caretaker
C. Client, Proxy, RealSubject
D. Component, Decorator, ConcreteComponent

Solution

  1. Step 1: Identify components of Memento pattern

    The Memento pattern consists of three main parts: Originator (the object whose state is saved), Memento (the object storing the state), and Caretaker (manages mementos).
  2. Step 2: Eliminate other patterns

    Options B, C, and D correspond to Observer, Proxy, and Decorator patterns respectively, which are unrelated to Memento.
  3. Final Answer:

    Originator, Memento, Caretaker -> Option B
  4. Quick Check:

    Components = Originator + Memento + Caretaker [OK]
Hint: Remember 3 parts: Originator, Memento, Caretaker [OK]
Common Mistakes:
  • Mixing Memento components with Observer or Proxy
  • Forgetting the Caretaker role
  • Confusing Memento with Decorator pattern
3. Consider this simplified Python code using the Memento pattern:
class Memento:
    def __init__(self, state):
        self._state = state

class Originator:
    def __init__(self):
        self._state = ""
    def set_state(self, state):
        self._state = state
    def save(self):
        return Memento(self._state)
    def restore(self, memento):
        self._state = memento._state

originator = Originator()
originator.set_state("State1")
memento = originator.save()
originator.set_state("State2")
originator.restore(memento)
print(originator._state)

What will be printed?
medium
A. None
B. State2
C. State1
D. Error

Solution

  1. Step 1: Trace state changes in Originator

    Initially, Originator's state is set to "State1". Then a Memento is saved capturing "State1". Next, state changes to "State2".
  2. Step 2: Restore state from Memento

    Calling restore with the saved Memento sets the state back to "State1". The print statement outputs the restored state.
  3. Final Answer:

    State1 -> Option C
  4. Quick Check:

    Restore resets state to saved value [OK]
Hint: Restore sets state back to saved snapshot [OK]
Common Mistakes:
  • Assuming print shows latest state before restore
  • Confusing save and restore methods
  • Expecting error due to private variable access
4. In the following code snippet, what is the main issue that breaks the Memento pattern?
class Originator:
    def __init__(self):
        self._state = ""
    def set_state(self, state):
        self._state = state
    def save(self):
        return self._state  # returns state directly
    def restore(self, memento):
        self._state = memento

originator = Originator()
originator.set_state("State1")
memento = originator.save()
originator.set_state("State2")
originator.restore(memento)
print(originator._state)
medium
A. The save method returns state directly, exposing internal details
B. The restore method does not update the state
C. The Originator class lacks a Memento class
D. The set_state method is missing

Solution

  1. Step 1: Analyze the save method

    The save method returns the internal state directly instead of encapsulating it in a Memento object, exposing internal details.
  2. Step 2: Understand Memento pattern principle

    The pattern requires hiding the internal state inside a Memento object to prevent external access. Returning raw state breaks encapsulation.
  3. Final Answer:

    The save method returns state directly, exposing internal details -> Option A
  4. Quick Check:

    Save must hide state in Memento [OK]
Hint: Save must return Memento, not raw state [OK]
Common Mistakes:
  • Thinking restore method is faulty
  • Believing Memento class is mandatory in code
  • Ignoring encapsulation principle
5. You are designing a text editor with undo functionality using the Memento pattern. Which approach best balances memory usage and undo capability?
hard
A. Store a Memento only after significant changes or at checkpoints
B. Store a Memento after every single character change
C. Store all changes as raw text snapshots without Memento objects
D. Do not store any state; rely on user to retype

Solution

  1. Step 1: Consider memory and undo tradeoff

    Storing a Memento after every character change (Store a Memento after every single character change) uses excessive memory and is inefficient.
  2. Step 2: Evaluate checkpoint strategy

    Storing Mementos after significant changes or checkpoints (Store a Memento only after significant changes or at checkpoints) reduces memory use while allowing meaningful undo steps.
  3. Step 3: Assess other options

    Store all changes as raw text snapshots without Memento objects wastes memory by storing raw snapshots without encapsulation; Do not store any state; rely on user to retype removes undo capability.
  4. Final Answer:

    Store a Memento only after significant changes or at checkpoints -> Option A
  5. Quick Check:

    Checkpoint Mementos balance memory and undo [OK]
Hint: Save states at checkpoints, not every keystroke [OK]
Common Mistakes:
  • Saving state too frequently causing memory bloat
  • Ignoring encapsulation by storing raw snapshots
  • Not implementing undo at all