Example 1

Use case: Create an undo mechanism while printing characters on the screen

First create the Editor class which will save some content

<?php

class EditorOriginator
{
    private $content;

    public function saveState(): EditorStateMemento
    {
        return new EditorStateMemento($this->getContent());
    }

    public function restore(?EditorStateMemento $stateMemento): void
    {
        if ( !is_null($stateMemento) ) {
            $this->setContent($stateMemento->getContent());
        }
    }

    /**
     * @return string
     */
    public function getContent(): string
    {
        return $this->content;
    }

    /**
     * @param string $content
     */
    public function setContent(string $content): void
    {
        $this->content = $content;
    }
}

 

We need to save the current state of the content if we want to

<?php

class EditorStateMemento
{
    private $content;

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

    public function getContent(): string
    {
        return $this->content;
    }
}

And finally because we want to undo the content we need to store a history stack of the states we want to undo to

<?php

class HistoryCareTaker
{
    private $states = [];

    public function push(EditorStateMemento $stateMemento)
    {
        $this->states[] = $stateMemento;
    }

    public function pop(): ?EditorStateMemento
    {
        if ( !isset($this->states[count($this->states) - 1]) )
            return null;

        $lastState = $this->states[count($this->states) - 1];
        unset($this->states[count($this->states) - 1]);
        return $lastState;
    }
}

 

The client code

<?php

$editor = new \App\Behavioral\ExampleOne\EditorOriginator();
$history = new \App\Behavioral\ExampleOne\HistoryCareTaker();

$editor->setContent('a');
$history->push($editor->saveState());
echo $editor->getContent() . PHP_EOL;
$editor->setContent('b');
$history->push($editor->saveState());
echo $editor->getContent() . PHP_EOL;
$editor->setContent('c');
$history->push($editor->saveState());
echo $editor->getContent() . PHP_EOL;

echo 'Restore' . PHP_EOL;
$editor->restore($history->pop());
echo $editor->getContent() . PHP_EOL;
$editor->restore($history->pop());
echo $editor->getContent() . PHP_EOL;
$editor->restore($history->pop());
echo $editor->getContent() . PHP_EOL;
$editor->restore($history->pop());
echo $editor->getContent() . PHP_EOL;


// Output
a
b
c
Restore
c
b
a
a