From 314fc18556b46a0fc5e409a9e139c6ecef8c6e20 Mon Sep 17 00:00:00 2001 From: X25 Date: Sun, 13 Apr 2014 19:51:37 +0400 Subject: [PATCH] Implemented Memento Pattern --- Memento/Caretaker.php | 33 ++++++++++++++++++++++++++++++++ Memento/Memento.php | 25 ++++++++++++++++++++++++ Memento/Originator.php | 33 ++++++++++++++++++++++++++++++++ Memento/README.md | 18 ++++++++++++++++++ README.md | 1 + Tests/Memento/MementoTest.php | 36 +++++++++++++++++++++++++++++++++++ 6 files changed, 146 insertions(+) create mode 100644 Memento/Caretaker.php create mode 100644 Memento/Memento.php create mode 100644 Memento/Originator.php create mode 100644 Memento/README.md create mode 100644 Tests/Memento/MementoTest.php diff --git a/Memento/Caretaker.php b/Memento/Caretaker.php new file mode 100644 index 0000000..9c24357 --- /dev/null +++ b/Memento/Caretaker.php @@ -0,0 +1,33 @@ +setState("State1"); + //Setting state to State2 + $originator->setState("State2"); + //Saving State2 to Memento + $savedStates[] = $originator->saveToMemento(); + //Setting state to State3 + $originator->setState("State3"); + + // We can request multiple mementos, and choose which one to roll back to. + // Saving State3 to Memento + $savedStates[] = $originator->saveToMemento(); + //Setting state to State4 + $originator->setState("State4"); + + $originator->restoreFromMemento($savedStates[1]); + //State after restoring from Memento: State3 + } +} diff --git a/Memento/Memento.php b/Memento/Memento.php new file mode 100644 index 0000000..33e0dca --- /dev/null +++ b/Memento/Memento.php @@ -0,0 +1,25 @@ +state = $stateToSave; + } + + /** + * @return string + */ + public function getState() + { + return $this->state; + } +} diff --git a/Memento/Originator.php b/Memento/Originator.php new file mode 100644 index 0000000..6f1b9a7 --- /dev/null +++ b/Memento/Originator.php @@ -0,0 +1,33 @@ +state = $state; + } + + /** + * @return Memento + */ + public function saveToMemento() + { + return new Memento($this->state); + } + + public function restoreFromMemento(Memento $memento) + { + $this->state = $memento->getState(); + } +} diff --git a/Memento/README.md b/Memento/README.md new file mode 100644 index 0000000..83ca2c0 --- /dev/null +++ b/Memento/README.md @@ -0,0 +1,18 @@ +# Memento + +## Purpose + +Provide the ability to restore an object to its previous state (undo via rollback). + +The memento pattern is implemented with three objects: the originator, a caretaker and a memento. +The originator is some object that has an internal state. +The caretaker is going to do something to the originator, but wants to be able to undo the change. +The caretaker first asks the originator for a memento object. Then it does whatever operation (or sequence of operations) it was going to do. +To roll back to the state before the operations, it returns the memento object to the originator. +The memento object itself is an opaque object (one which the caretaker cannot, or should not, change). +When using this pattern, care should be taken if the originator may change other objects or resources - the memento pattern operates on a single object. + +## Examples + +* The seed of a pseudorandom number generator +* The state in a finite state machine diff --git a/README.md b/README.md index 56fd4df..2f9ba16 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ The patterns can be structured in roughly three different categories. Please cli * [Command](Command) [:notebook:](http://en.wikipedia.org/wiki/Command_pattern) * [Iterator](Iterator) [:notebook:](http://en.wikipedia.org/wiki/Iterator_pattern) * [Mediator](Mediator) [:notebook:](http://en.wikipedia.org/wiki/Mediator_pattern) +* [Memento](Memento) [:notebook:](http://http://en.wikipedia.org/wiki/Memento_pattern) * [NullObject](NullObject) [:notebook:](http://en.wikipedia.org/wiki/Null_Object_pattern) * [Observer](Observer) [:notebook:](http://en.wikipedia.org/wiki/Observer_pattern) * [Specification](Specification) [:notebook:](http://en.wikipedia.org/wiki/Specification_pattern) diff --git a/Tests/Memento/MementoTest.php b/Tests/Memento/MementoTest.php new file mode 100644 index 0000000..5fc8213 --- /dev/null +++ b/Tests/Memento/MementoTest.php @@ -0,0 +1,36 @@ +setState("State1"); + + $this->assertAttributeEquals("State1", "state", $originator); + + $originator->setState("State2"); + + $this->assertAttributeEquals("State2", "state", $originator); + + $savedState = $originator->saveToMemento(); + + $this->assertAttributeEquals("State2", "state", $savedState); + + $originator->setState("State3"); + + $this->assertAttributeEquals("State3", "state", $originator); + + $originator->restoreFromMemento($savedState); + + $this->assertAttributeEquals("State2", "state", $originator); + } +}