Memento Design Pattern in PHP

1. Definition

The Memento Design Pattern allows for the ability to restore an object to its previous state. This is typically used for "undo" functionalities in applications.

2. Problem Statement

Imagine working on a document editor. After making several changes, you realize that you want to revert back to a previous state. Without an "undo" mechanism, you'd be stuck with your changes and possibly have lost significant work.

3. Solution

The Memento pattern solves this problem by keeping snapshots of the object's state. These snapshots can be returned to, effectively allowing an "undo" operation.

4. Real-World Use Cases

1. Undo and redo functionality in text editors.

2. Saving game states in video games.

3. Taking system snapshots.

5. Implementation Steps

1. Create the Originator class with a state and methods to save it to and restore it from a memento.

2. Define the Memento class that will store the internal state of the Originator.

3. Implement a Caretaker class to keep track of multiple states if needed.

6. Implementation in PHP

<?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 setState($state) {
        $this->state = $state;
    }
    public function saveToMemento() {
        return new Memento($this->state);
    }
    public function restoreFromMemento(Memento $memento) {
        $this->state = $memento->getState();
    }
    public function getState() {
        return $this->state;
    }
}
// Caretaker
class Caretaker {
    private $savedStates = [];
    public function addMemento(Memento $memento) {
        $this->savedStates[] = $memento;
    }
    public function getMemento($index) {
        return $this->savedStates[$index];
    }
}
// Client Code
$originator = new Originator();
$caretaker = new Caretaker();
$originator->setState("State1");
$caretaker->addMemento($originator->saveToMemento());
$originator->setState("State2");
$caretaker->addMemento($originator->saveToMemento());
// Restore to State1
$originator->restoreFromMemento($caretaker->getMemento(0));
echo $originator->getState(); // Outputs: State1
?>

Output:

State1

Explanation:

1. Memento: Stores the state of the Originator.

2. Originator: The main object we want to save and restore states for.

3. Caretaker: Holds the different states of the Originator. It's like a collection of saved states.

4. In the client code, we set the state of the originator, save it, change the state, save it again, and then restore it to its first state.

7. When to use?

Use the Memento pattern when:

1. You need to implement a snapshot capability or undo mechanism.

2. Direct access to an object's state may expose details that should remain hidden.

3. You want to keep a history of states.


Comments