Bird
Raised Fist0
LLDsystem_design~7 mins

Memento pattern in LLD - System Design Guide

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
Problem Statement
When an object changes state frequently, it becomes difficult to restore it to a previous state without exposing its internal details. Without a controlled way to save and restore states, undo operations or rollback mechanisms can lead to errors or tight coupling between components.
Solution
The Memento pattern captures and externalizes an object's internal state without violating encapsulation, so the object can be restored to this state later. It uses a separate memento object to store the state, allowing the originator to save and restore its state safely.
Architecture
Client
Originator

This diagram shows the Client interacting with the Originator to save and restore state via the Memento object, which is managed by the Caretaker.

Trade-offs
✓ Pros
Preserves encapsulation by not exposing the internal state of the Originator.
Enables undo or rollback functionality by storing snapshots of state.
Separates state storage responsibility from the Originator, simplifying its design.
✗ Cons
Can increase memory usage if many states are saved as mementos.
Managing many mementos can add complexity to the Caretaker component.
Not suitable for very large or complex states without optimization.
Use when you need to implement undo/redo functionality or rollback state changes in an object without exposing its internals, especially when state changes are frequent but not continuous at very high scale.
Avoid when the object's state is very large or complex and saving/restoring state frequently would cause performance or memory issues.
Real World Examples
Microsoft Word
Uses the Memento pattern to implement undo and redo features by saving document states without exposing internal document structure.
Adobe Photoshop
Stores snapshots of image edits as mementos to allow users to revert to previous versions without exposing internal image data.
Eclipse IDE
Uses mementos to save and restore the state of UI components and editors during session persistence.
Code Example
Before applying the Memento pattern, the Editor exposes its internal state directly, risking tight coupling and breaking encapsulation. After applying the pattern, the Editor creates a Memento object to store its state, and the Caretaker manages these mementos. This keeps the Editor's state private and allows safe undo operations.
LLD
### Before (without Memento pattern):
class Editor:
    def __init__(self):
        self.content = ""

    def type(self, words):
        self.content += words

    def save(self):
        # No encapsulation, exposes internal state
        return self.content

    def restore(self, content):
        self.content = content


editor = Editor()
editor.type("Hello ")
saved = editor.save()
editor.type("World!")
print(editor.content)  # Hello World!
editor.restore(saved)
print(editor.content)  # Hello 


### After (with Memento pattern):

class Memento:
    def __init__(self, content):
        self._content = content

    def get_content(self):
        return self._content


class Editor:
    def __init__(self):
        self._content = ""

    def type(self, words):
        self._content += words

    def save(self):
        return Memento(self._content)

    def restore(self, memento):
        self._content = memento.get_content()

    def get_content(self):
        return self._content


class Caretaker:
    def __init__(self):
        self._mementos = []

    def save_state(self, editor):
        self._mementos.append(editor.save())

    def undo(self, editor):
        if not self._mementos:
            return
        memento = self._mementos.pop()
        editor.restore(memento)


editor = Editor()
caretaker = Caretaker()

editor.type("Hello ")
caretaker.save_state(editor)

editor.type("World!")
print(editor.get_content())  # Hello World!

caretaker.undo(editor)
print(editor.get_content())  # Hello 
OutputSuccess
Alternatives
Command pattern
Stores operations as objects that can be executed or undone, rather than storing the entire state snapshot.
Use when: Use when you want to record user actions as commands for undo/redo rather than full state snapshots.
Snapshot pattern
Similar to Memento but often involves deep copying or serialization of the entire object state.
Use when: Use when you need a full copy of the object's state and can afford the overhead.
Summary
The Memento pattern helps save and restore an object's state without exposing its internals.
It enables undo and rollback functionality by storing snapshots in separate memento objects.
This pattern preserves encapsulation and separates state management from the main object.

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