| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 9beb7d9 commit 14a9dfe
16 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,33 @@ | |||
| 1 | + <?php | ||
| 2 | + | ||
| 3 | + namespace DesignPatterns\Behavioral\Memento; | ||
| 4 | + | ||
| 5 | + class Caretaker | ||
| 6 | + { | ||
| 7 | + public static function run() | ||
| 8 | + { | ||
| 9 | + /* @var $savedStates Memento[] */ | ||
| 10 | + | ||
| 11 | + $savedStates = array(); | ||
| 12 | + | ||
| 13 | + $originator = new Originator(); | ||
| 14 | + | ||
| 15 | + //Setting state to State1 | ||
| 16 | + $originator->setState("State1"); | ||
| 17 | + //Setting state to State2 | ||
| 18 | + $originator->setState("State2"); | ||
| 19 | + //Saving State2 to Memento | ||
| 20 | + $savedStates[] = $originator->saveToMemento(); | ||
| 21 | + //Setting state to State3 | ||
| 22 | + $originator->setState("State3"); | ||
| 23 | + | ||
| 24 | + // We can request multiple mementos, and choose which one to roll back to. | ||
| 25 | + // Saving State3 to Memento | ||
| 26 | + $savedStates[] = $originator->saveToMemento(); | ||
| 27 | + //Setting state to State4 | ||
| 28 | + $originator->setState("State4"); | ||
| 29 | + | ||
| 30 | + $originator->restoreFromMemento($savedStates[1]); | ||
| 31 | + //State after restoring from Memento: State3 | ||
| 32 | + } | ||
| 33 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,25 @@ | |||
| 1 | + <?php | ||
| 2 | + | ||
| 3 | + namespace DesignPatterns\Behavioral\Memento; | ||
| 4 | + | ||
| 5 | + class Memento | ||
| 6 | + { | ||
| 7 | + /* @var mixed */ | ||
| 8 | + private $state; | ||
| 9 | + | ||
| 10 | + /** | ||
| 11 | + * @param mixed $stateToSave | ||
| 12 | + */ | ||
| 13 | + public function __construct($stateToSave) | ||
| 14 | + { | ||
| 15 | + $this->state = $stateToSave; | ||
| 16 | + } | ||
| 17 | + | ||
| 18 | + /** | ||
| 19 | + * @return mixed | ||
| 20 | + */ | ||
| 21 | + public function getState() | ||
| 22 | + { | ||
| 23 | + return $this->state; | ||
| 24 | + } | ||
| 25 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,67 @@ | |||
| 1 | + <?php | ||
| 2 | + | ||
| 3 | + namespace DesignPatterns\Behavioral\Memento; | ||
| 4 | + | ||
| 5 | + /** | ||
| 6 | + * MementoTest tests the memento pattern | ||
| 7 | + */ | ||
| 8 | + class MementoTest extends \PHPUnit_Framework_TestCase | ||
| 9 | + { | ||
| 10 | + | ||
| 11 | + public function testStringState() | ||
| 12 | + { | ||
| 13 | + $originator = new Originator(); | ||
| 14 | + $originator->setState("State1"); | ||
| 15 | + | ||
| 16 | + $this->assertAttributeEquals("State1", "state", $originator); | ||
| 17 | + | ||
| 18 | + $originator->setState("State2"); | ||
| 19 | + | ||
| 20 | + $this->assertAttributeEquals("State2", "state", $originator); | ||
| 21 | + | ||
| 22 | + $savedState = $originator->saveToMemento(); | ||
| 23 | + | ||
| 24 | + $this->assertAttributeEquals("State2", "state", $savedState); | ||
| 25 | + | ||
| 26 | + $originator->setState("State3"); | ||
| 27 | + | ||
| 28 | + $this->assertAttributeEquals("State3", "state", $originator); | ||
| 29 | + | ||
| 30 | + $originator->restoreFromMemento($savedState); | ||
| 31 | + | ||
| 32 | + $this->assertAttributeEquals("State2", "state", $originator); | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + public function testObjectState() | ||
| 36 | + { | ||
| 37 | + $originator = new Originator(); | ||
| 38 | + | ||
| 39 | + $foo = new \stdClass(); | ||
| 40 | + $foo->data = "foo"; | ||
| 41 | + | ||
| 42 | + $originator->setState($foo); | ||
| 43 | + | ||
| 44 | + $this->assertAttributeEquals($foo, "state", $originator); | ||
| 45 | + | ||
| 46 | + $savedState = $originator->saveToMemento(); | ||
| 47 | + | ||
| 48 | + $this->assertAttributeEquals($foo, "state", $savedState); | ||
| 49 | + | ||
| 50 | + $bar = new \stdClass(); | ||
| 51 | + $bar->data = "bar"; | ||
| 52 | + | ||
| 53 | + $originator->setState($bar); | ||
| 54 | + | ||
| 55 | + $this->assertAttributeEquals($bar, "state", $originator); | ||
| 56 | + | ||
| 57 | + $originator->restoreFromMemento($savedState); | ||
| 58 | + | ||
| 59 | + $this->assertAttributeEquals($foo, "state", $originator); | ||
| 60 | + | ||
| 61 | + $foo->data = null; | ||
| 62 | + | ||
| 63 | + $this->assertAttributeNotEquals($foo, "state", $savedState); | ||
| 64 | + | ||
| 65 | + $this->assertAttributeNotEquals($foo, "state", $originator); | ||
| 66 | + } | ||
| 67 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,35 @@ | |||
| 1 | + <?php | ||
| 2 | + | ||
| 3 | + namespace DesignPatterns\Behavioral\Memento; | ||
| 4 | + | ||
| 5 | + class Originator | ||
| 6 | + { | ||
| 7 | + /* @var mixed */ | ||
| 8 | + private $state; | ||
| 9 | + | ||
| 10 | + // The class could also contain additional data that is not part of the | ||
| 11 | + // state saved in the memento.. | ||
| 12 | + | ||
| 13 | + /** | ||
| 14 | + * @param mixed $state | ||
| 15 | + */ | ||
| 16 | + public function setState($state) | ||
| 17 | + { | ||
| 18 | + $this->state = $state; | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + /** | ||
| 22 | + * @return Memento | ||
| 23 | + */ | ||
| 24 | + public function saveToMemento() | ||
| 25 | + { | ||
| 26 | + $state = is_object($this->state) ? clone $this->state : $this->state; | ||
| 27 | + | ||
| 28 | + return new Memento($state); | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + public function restoreFromMemento(Memento $memento) | ||
| 32 | + { | ||
| 33 | + $this->state = $memento->getState(); | ||
| 34 | + } | ||
| 35 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,18 @@ | |||
| 1 | + # Memento | ||
| 2 | + | ||
| 3 | + ## Purpose | ||
| 4 | + | ||
| 5 | + Provide the ability to restore an object to its previous state (undo via rollback). | ||
| 6 | + | ||
| 7 | + The memento pattern is implemented with three objects: the originator, a caretaker and a memento. | ||
| 8 | + The originator is some object that has an internal state. | ||
| 9 | + The caretaker is going to do something to the originator, but wants to be able to undo the change. | ||
| 10 | + The caretaker first asks the originator for a memento object. Then it does whatever operation (or sequence of operations) it was going to do. | ||
| 11 | + To roll back to the state before the operations, it returns the memento object to the originator. | ||
| 12 | + The memento object itself is an opaque object (one which the caretaker cannot, or should not, change). | ||
| 13 | + 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. | ||
| 14 | + | ||
| 15 | + ## Examples | ||
| 16 | + | ||
| 17 | + * The seed of a pseudorandom number generator | ||
| 18 | + * The state in a finite state machine | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -26,22 +26,15 @@ class ServiceLocatorTest extends TestCase | |||
| 26 | 26 | ||
| 27 | 27 | public function setUp() | |
| 28 | 28 | { | |
| 29 | - $this->serviceLocator = new ServiceLocator(); | ||
| 30 | - | ||
| 31 | - $this->logService = new LogService(); | ||
| 29 | + $this->serviceLocator = new ServiceLocator(); | ||
| 30 | + $this->logService = new LogService(); | ||
| 32 | 31 | $this->databaseService = new DatabaseService(); | |
| 33 | 32 | } | |
| 34 | 33 | ||
| 35 | 34 | public function testHasServices() | |
| 36 | 35 | { | |
| 37 | - $this->serviceLocator->add( | ||
| 38 | - 'DesignPatterns\More\ServiceLocator\LogServiceInterface', | ||
| 39 | - $this->logService | ||
| 40 | - ); | ||
| 41 | - $this->serviceLocator->add( | ||
| 42 | - 'DesignPatterns\More\ServiceLocator\DatabaseServiceInterface', | ||
| 43 | - $this->databaseService | ||
| 44 | - ); | ||
| 36 | + $this->serviceLocator->add('DesignPatterns\More\ServiceLocator\LogServiceInterface', $this->logService); | ||
| 37 | + $this->serviceLocator->add('DesignPatterns\More\ServiceLocator\DatabaseServiceInterface', $this->databaseService); | ||
| 45 | 38 | ||
| 46 | 39 | $this->assertTrue($this->serviceLocator->has('DesignPatterns\More\ServiceLocator\LogServiceInterface')); | |
| 47 | 40 | $this->assertTrue($this->serviceLocator->has('DesignPatterns\More\ServiceLocator\DatabaseServiceInterface')); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14,17 +14,18 @@ The patterns can be structured in roughly three different categories. Please cli | |||
| 14 | 14 | ||
| 15 | 15 | * [AbstractFactory](Creational/AbstractFactory) [:notebook:](http://en.wikipedia.org/wiki/Abstract_factory_pattern) | |
| 16 | 16 | * [Builder](Creational/Builder) [:notebook:](http://en.wikipedia.org/wiki/Builder_pattern) | |
| 17 | - * [SimpleFactory](Creational/SimpleFactory) | ||
| 18 | 17 | * [FactoryMethod](Creational/FactoryMethod) [:notebook:](http://en.wikipedia.org/wiki/Factory_method_pattern) | |
| 19 | - * [StaticFactory](Creational/StaticFactory) | ||
| 20 | - * [Prototype](Creational/Prototype) [:notebook:](http://en.wikipedia.org/wiki/Prototype_pattern) | ||
| 18 | + * [Multiton](Creational/Multiton) (is considered an anti-pattern! :no_entry:) | ||
| 21 | 19 | * [Pool](Creational/Pool) [:notebook:](http://en.wikipedia.org/wiki/Object_pool_pattern) | |
| 20 | + * [Prototype](Creational/Prototype) [:notebook:](http://en.wikipedia.org/wiki/Prototype_pattern) | ||
| 21 | + * [SimpleFactory](Creational/SimpleFactory) | ||
| 22 | 22 | * [Singleton](Creational/Singleton) [:notebook:](http://en.wikipedia.org/wiki/Singleton_pattern) (is considered an anti-pattern! :no_entry:) | |
| 23 | - * [Multiton](Creational/Multiton) (is considered an anti-pattern! :no_entry:) | ||
| 23 | + * [StaticFactory](Creational/StaticFactory) | ||
| 24 | 24 | ||
| 25 | 25 | ### [Structural](Structural) | |
| 26 | 26 | ||
| 27 | 27 | * [Adapter](Structural/Adapter) [:notebook:](http://en.wikipedia.org/wiki/Adapter_pattern) | |
| 28 | + * [Bridge](Structural/Bridge) [:notebook:](http://en.wikipedia.org/wiki/Bridge_pattern) | ||
| 28 | 29 | * [Composite](Structural/Composite) [:notebook:](http://en.wikipedia.org/wiki/Composite_pattern) | |
| 29 | 30 | * [DataMapper](Structural/DataMapper) [:notebook:](http://en.wikipedia.org/wiki/Data_mapper_pattern) | |
| 30 | 31 | * [Decorator](Structural/Decorator) [:notebook:](http://en.wikipedia.org/wiki/Decorator_pattern) | |
@@ -40,6 +41,7 @@ The patterns can be structured in roughly three different categories. Please cli | |||
| 40 | 41 | * [Command](Behavioral/Command) [:notebook:](http://en.wikipedia.org/wiki/Command_pattern) | |
| 41 | 42 | * [Iterator](Behavioral/Iterator) [:notebook:](http://en.wikipedia.org/wiki/Iterator_pattern) | |
| 42 | 43 | * [Mediator](Behavioral/Mediator) [:notebook:](http://en.wikipedia.org/wiki/Mediator_pattern) | |
| 44 | + * [Memento](Memento) [:notebook:](http://en.wikipedia.org/wiki/Memento_pattern) | ||
| 43 | 45 | * [NullObject](Behavioral/NullObject) [:notebook:](http://en.wikipedia.org/wiki/Null_Object_pattern) | |
| 44 | 46 | * [Observer](Behavioral/Observer) [:notebook:](http://en.wikipedia.org/wiki/Observer_pattern) | |
| 45 | 47 | * [Specification](Behavioral/Specification) [:notebook:](http://en.wikipedia.org/wiki/Specification_pattern) | |
@@ -61,7 +63,7 @@ To establish a consistent code quality, please check your code using [PHP_CodeSn | |||
| 61 | 63 | ||
| 62 | 64 | (The MIT License) | |
| 63 | 65 | ||
| 64 | - Copyright (c) 2013 Dominik Liebler | ||
| 66 | + Copyright (c) 2014 Dominik Liebler | ||
| 65 | 67 | ||
| 66 | 68 | Permission is hereby granted, free of charge, to any person obtaining | |
| 67 | 69 | a copy of this software and associated documentation files (the | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,12 @@ | |||
| 1 | + <?php | ||
| 2 | + | ||
| 3 | + namespace DesignPatterns\Structural\Bridge; | ||
| 4 | + | ||
| 5 | + class Assemble implements Workshop | ||
| 6 | + { | ||
| 7 | + | ||
| 8 | + public function work() | ||
| 9 | + { | ||
| 10 | + print 'Assembled'; | ||
| 11 | + } | ||
| 12 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,21 @@ | |||
| 1 | + <?php | ||
| 2 | + | ||
| 3 | + namespace DesignPatterns\Structural\Bridge; | ||
| 4 | + | ||
| 5 | + class BridgeTest extends \PHPUnit_Framework_TestCase | ||
| 6 | + { | ||
| 7 | + | ||
| 8 | + public function testCar() | ||
| 9 | + { | ||
| 10 | + $vehicle = new Car(new Produce(), new Assemble()); | ||
| 11 | + $this->expectOutputString('Car Produced Assembled'); | ||
| 12 | + $vehicle->manufacture(); | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | + public function testMotorcycle() | ||
| 16 | + { | ||
| 17 | + $vehicle = new Motorcycle(new Produce(), new Assemble()); | ||
| 18 | + $this->expectOutputString('Motorcycle Produced Assembled'); | ||
| 19 | + $vehicle->manufacture(); | ||
| 20 | + } | ||
| 21 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,22 @@ | |||
| 1 | + <?php | ||
| 2 | + | ||
| 3 | + namespace DesignPatterns\Structural\Bridge; | ||
| 4 | + | ||
| 5 | + /** | ||
| 6 | + * Refined Abstraction | ||
| 7 | + */ | ||
| 8 | + class Car extends Vehicle | ||
| 9 | + { | ||
| 10 | + | ||
| 11 | + public function __construct(Workshop $workShop1, Workshop $workShop2) | ||
| 12 | + { | ||
| 13 | + parent::__construct($workShop1, $workShop2); | ||
| 14 | + } | ||
| 15 | + | ||
| 16 | + public function manufacture() | ||
| 17 | + { | ||
| 18 | + print 'Car '; | ||
| 19 | + $this->workShop1->work(); | ||
| 20 | + $this->workShop2->work(); | ||
| 21 | + } | ||
| 22 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments