The Memento pattern is a behavioral design pattern that allows for capturing and externalizing an object’s internal state without violating encapsulation, so that the object can be restored to that state later. This pattern is often used to implement undo/redo functionality in applications.

Key Characteristics:

  • State Capture: Captures and stores the internal state of an object.
  • Restoration: Allows restoring an object to a previous state.
  • Encapsulation Preservation: Does not expose the internal details of the object to outside classes.

How It Works:

  • Memento: Stores the internal state of the originator object. It provides access to this state but does not allow modification.
  • Originator: The object whose state needs to be captured and restored. It creates a memento containing a snapshot of its current state.
  • Caretaker: Manages the memento and is responsible for keeping and restoring it. It does not modify the memento or know the details of the state it holds.

Example in PHP:

  // Memento
class Memento {
    private $state;

    public function __construct($state) {
        $this->state = $state;
    }

    public function getState() {
        return $this->state;
    }
}

// Originator
class Originator {
    private $state;

    public function __construct($state) {
        $this->state = $state;
    }

    public function setState($state) {
        $this->state = $state;
    }

    public function getState() {
        return $this->state;
    }

    public function createMemento() {
        return new Memento($this->state);
    }

    public function restoreMemento(Memento $memento) {
        $this->state = $memento->getState();
    }
}

// Caretaker
class Caretaker {
    private $mementos = [];

    public function addMemento(Memento $memento) {
        $this->mementos[] = $memento;
    }

    public function getMemento($index) {
        return $this->mementos[$index];
    }
}

// Client Code
$originator = new Originator("State1");
$caretaker = new Caretaker();

// Save the current state
$caretaker->addMemento($originator->createMemento());

$originator->setState("State2");
echo "Current State: " . $originator->getState() . "\n"; // Output: Current State: State2

// Restore the previous state
$originator->restoreMemento($caretaker->getMemento(0));
echo "Restored State: " . $originator->getState() . "\n"; // Output: Restored State: State1
  

Explanation:

  1. Memento: Memento class stores the state of the Originator. It only allows access to the stored state.
  2. Originator: Originator class creates and restores Memento objects. It manages its own state and can create a memento representing its current state.
  3. Caretaker: Caretaker class manages the collection of mementos and is responsible for saving and restoring them.

Benefits:

  • Encapsulation: Keeps the internal state of an object private while allowing state restoration.
  • Undo/Redo Functionality: Supports undo/redo functionality by storing and restoring states.
  • State Management: Simplifies the management of different states of an object.

Use Cases:

  • Undo/Redo Operations: Implementing undo and redo functionalities in text editors, drawing applications, etc.
  • Stateful Applications: Applications where objects need to be reverted to previous states.
  • Checkpointing: For creating checkpoints in processes where rollback to previous states is required.

The Memento pattern is useful for capturing and restoring an object’s state while preserving encapsulation, making it ideal for implementing undo/redo features and managing complex state transitions in an application.