08 Jan 2025

Memento Pattern

Memento Pattern

Overview

The Memento Pattern is a behavioral design pattern that allows you to capture and restore the state of an object without exposing its internal details. This is particularly useful for implementing undo/redo functionality.

Key Participants

  1. Memento

  • Stores the internal state of the Originator.

  • Protects the state from access by objects other than the Originator.

  1. Originator

  • The object whose state needs to be saved and restored.

  • Creates and restores its state from a Memento.

  1. Caretaker

  • Responsible for keeping track of mementos.

  • Does not modify or operate on the mementos but knows when to save or restore the state of the Originator.

Implementation in Code

Example: Text Editor Undo Functionality

// Memento
class TextMemento {
    private final String state;

    public TextMemento(String state) {
        this.state = state;
    }

    public String getState() {
        return state;
    }
}

// Originator
class TextEditor {
    private String text;

    public void setText(String text) {
        this.text = text;
    }

    public String getText() {
        return text;
    }

    public TextMemento save() {
        return new TextMemento(text);
    }

    public void restore(TextMemento memento) {
        text = memento.getState();
    }
}

// Caretaker
class TextHistory {
    private final Stack<TextMemento> history = new Stack<>();

    public void save(TextEditor editor) {
        history.push(editor.save());
    }

    public void undo(TextEditor editor) {
        if (!history.isEmpty()) {
            editor.restore(history.pop());
        } else {
            System.out.println("No states to undo.");
        }
    }
}

// Client
public class MementoPatternDemo {
    public static void main(String[] args) {
        TextEditor editor = new TextEditor();
        TextHistory history = new TextHistory();

        editor.setText("Version 1");
        history.save(editor);

        editor.setText("Version 2");
        history.save(editor);

        editor.setText("Version 3");

        System.out.println("Current Text: " + editor.getText());

        history.undo(editor);
        System.out.println("After Undo: " + editor.getText());

        history.undo(editor);
        System.out.println("After Undo: " + editor.getText());
    }
}

Key Methods

  1. save(): Captures the current state of the Originator in a Memento.

  1. restore(Memento): Restores the state of the Originator from a Memento.

Advantages

  1. Encapsulation: The Originator’s state is saved without exposing internal details.

  1. Undo/Redo: Easily supports undo/redo functionality.

  1. Decoupling: The Caretaker does not need to know the details of the Originator.

Disadvantages

  1. Memory Overhead: Saving states can consume significant memory if the object is large or changes frequently.

  1. Complexity: Managing a large number of mementos can become complex.

Real-World Examples

  1. Text Editors: Undo/redo functionality to restore previous states of a document.

  1. Game Save System: Saving the state of a game for restoring later.

  1. Configuration Management: Restoring previous configurations of an application.

When to Use the Memento Pattern?

  • When you need to save and restore an object’s state.

  • When implementing undo/redo functionality.

  • When you want to preserve encapsulation of the object’s internal state.

← Back to Library