mirror of
https://github.com/DesignPatternsPHP/DesignPatternsPHP.git
synced 2025-07-25 17:21:19 +02:00
merge from master
This commit is contained in:
33
Behavioral/Memento/Caretaker.php
Normal file
33
Behavioral/Memento/Caretaker.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\Behavioral\Memento;
|
||||
|
||||
class Caretaker
|
||||
{
|
||||
public static function run()
|
||||
{
|
||||
/* @var $savedStates Memento[] */
|
||||
|
||||
$savedStates = array();
|
||||
|
||||
$originator = new Originator();
|
||||
|
||||
//Setting state to State1
|
||||
$originator->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
|
||||
}
|
||||
}
|
25
Behavioral/Memento/Memento.php
Normal file
25
Behavioral/Memento/Memento.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\Behavioral\Memento;
|
||||
|
||||
class Memento
|
||||
{
|
||||
/* @var mixed */
|
||||
private $state;
|
||||
|
||||
/**
|
||||
* @param mixed $stateToSave
|
||||
*/
|
||||
public function __construct($stateToSave)
|
||||
{
|
||||
$this->state = $stateToSave;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getState()
|
||||
{
|
||||
return $this->state;
|
||||
}
|
||||
}
|
67
Behavioral/Memento/MementoTest.php
Normal file
67
Behavioral/Memento/MementoTest.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\Behavioral\Memento;
|
||||
|
||||
/**
|
||||
* MementoTest tests the memento pattern
|
||||
*/
|
||||
class MementoTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
public function testStringState()
|
||||
{
|
||||
$originator = new Originator();
|
||||
$originator->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);
|
||||
}
|
||||
|
||||
public function testObjectState()
|
||||
{
|
||||
$originator = new Originator();
|
||||
|
||||
$foo = new \stdClass();
|
||||
$foo->data = "foo";
|
||||
|
||||
$originator->setState($foo);
|
||||
|
||||
$this->assertAttributeEquals($foo, "state", $originator);
|
||||
|
||||
$savedState = $originator->saveToMemento();
|
||||
|
||||
$this->assertAttributeEquals($foo, "state", $savedState);
|
||||
|
||||
$bar = new \stdClass();
|
||||
$bar->data = "bar";
|
||||
|
||||
$originator->setState($bar);
|
||||
|
||||
$this->assertAttributeEquals($bar, "state", $originator);
|
||||
|
||||
$originator->restoreFromMemento($savedState);
|
||||
|
||||
$this->assertAttributeEquals($foo, "state", $originator);
|
||||
|
||||
$foo->data = null;
|
||||
|
||||
$this->assertAttributeNotEquals($foo, "state", $savedState);
|
||||
|
||||
$this->assertAttributeNotEquals($foo, "state", $originator);
|
||||
}
|
||||
}
|
35
Behavioral/Memento/Originator.php
Normal file
35
Behavioral/Memento/Originator.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\Behavioral\Memento;
|
||||
|
||||
class Originator
|
||||
{
|
||||
/* @var mixed */
|
||||
private $state;
|
||||
|
||||
// The class could also contain additional data that is not part of the
|
||||
// state saved in the memento..
|
||||
|
||||
/**
|
||||
* @param mixed $state
|
||||
*/
|
||||
public function setState($state)
|
||||
{
|
||||
$this->state = $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Memento
|
||||
*/
|
||||
public function saveToMemento()
|
||||
{
|
||||
$state = is_object($this->state) ? clone $this->state : $this->state;
|
||||
|
||||
return new Memento($state);
|
||||
}
|
||||
|
||||
public function restoreFromMemento(Memento $memento)
|
||||
{
|
||||
$this->state = $memento->getState();
|
||||
}
|
||||
}
|
18
Behavioral/Memento/README.md
Normal file
18
Behavioral/Memento/README.md
Normal file
@@ -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
|
@@ -26,22 +26,15 @@ class ServiceLocatorTest extends TestCase
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->serviceLocator = new ServiceLocator();
|
||||
|
||||
$this->logService = new LogService();
|
||||
$this->serviceLocator = new ServiceLocator();
|
||||
$this->logService = new LogService();
|
||||
$this->databaseService = new DatabaseService();
|
||||
}
|
||||
|
||||
public function testHasServices()
|
||||
{
|
||||
$this->serviceLocator->add(
|
||||
'DesignPatterns\More\ServiceLocator\LogServiceInterface',
|
||||
$this->logService
|
||||
);
|
||||
$this->serviceLocator->add(
|
||||
'DesignPatterns\More\ServiceLocator\DatabaseServiceInterface',
|
||||
$this->databaseService
|
||||
);
|
||||
$this->serviceLocator->add('DesignPatterns\More\ServiceLocator\LogServiceInterface', $this->logService);
|
||||
$this->serviceLocator->add('DesignPatterns\More\ServiceLocator\DatabaseServiceInterface', $this->databaseService);
|
||||
|
||||
$this->assertTrue($this->serviceLocator->has('DesignPatterns\More\ServiceLocator\LogServiceInterface'));
|
||||
$this->assertTrue($this->serviceLocator->has('DesignPatterns\More\ServiceLocator\DatabaseServiceInterface'));
|
||||
|
14
README.md
14
README.md
@@ -14,17 +14,18 @@ The patterns can be structured in roughly three different categories. Please cli
|
||||
|
||||
* [AbstractFactory](Creational/AbstractFactory) [:notebook:](http://en.wikipedia.org/wiki/Abstract_factory_pattern)
|
||||
* [Builder](Creational/Builder) [:notebook:](http://en.wikipedia.org/wiki/Builder_pattern)
|
||||
* [SimpleFactory](Creational/SimpleFactory)
|
||||
* [FactoryMethod](Creational/FactoryMethod) [:notebook:](http://en.wikipedia.org/wiki/Factory_method_pattern)
|
||||
* [StaticFactory](Creational/StaticFactory)
|
||||
* [Prototype](Creational/Prototype) [:notebook:](http://en.wikipedia.org/wiki/Prototype_pattern)
|
||||
* [Pool](Creational/Pool) [:notebook:](http://en.wikipedia.org/wiki/Object_pool_pattern)
|
||||
* [Singleton](Creational/Singleton) [:notebook:](http://en.wikipedia.org/wiki/Singleton_pattern) (is considered an anti-pattern! :no_entry:)
|
||||
* [Multiton](Creational/Multiton) (is considered an anti-pattern! :no_entry:)
|
||||
* [Pool](Creational/Pool) [:notebook:](http://en.wikipedia.org/wiki/Object_pool_pattern)
|
||||
* [Prototype](Creational/Prototype) [:notebook:](http://en.wikipedia.org/wiki/Prototype_pattern)
|
||||
* [SimpleFactory](Creational/SimpleFactory)
|
||||
* [Singleton](Creational/Singleton) [:notebook:](http://en.wikipedia.org/wiki/Singleton_pattern) (is considered an anti-pattern! :no_entry:)
|
||||
* [StaticFactory](Creational/StaticFactory)
|
||||
|
||||
### [Structural](Structural)
|
||||
|
||||
* [Adapter](Structural/Adapter) [:notebook:](http://en.wikipedia.org/wiki/Adapter_pattern)
|
||||
* [Bridge](Structural/Bridge) [:notebook:](http://en.wikipedia.org/wiki/Bridge_pattern)
|
||||
* [Composite](Structural/Composite) [:notebook:](http://en.wikipedia.org/wiki/Composite_pattern)
|
||||
* [DataMapper](Structural/DataMapper) [:notebook:](http://en.wikipedia.org/wiki/Data_mapper_pattern)
|
||||
* [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
|
||||
* [Command](Behavioral/Command) [:notebook:](http://en.wikipedia.org/wiki/Command_pattern)
|
||||
* [Iterator](Behavioral/Iterator) [:notebook:](http://en.wikipedia.org/wiki/Iterator_pattern)
|
||||
* [Mediator](Behavioral/Mediator) [:notebook:](http://en.wikipedia.org/wiki/Mediator_pattern)
|
||||
* [Memento](Memento) [:notebook:](http://en.wikipedia.org/wiki/Memento_pattern)
|
||||
* [NullObject](Behavioral/NullObject) [:notebook:](http://en.wikipedia.org/wiki/Null_Object_pattern)
|
||||
* [Observer](Behavioral/Observer) [:notebook:](http://en.wikipedia.org/wiki/Observer_pattern)
|
||||
* [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
|
||||
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2013 Dominik Liebler
|
||||
Copyright (c) 2014 Dominik Liebler
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
12
Structural/Bridge/Assemble.php
Normal file
12
Structural/Bridge/Assemble.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\Structural\Bridge;
|
||||
|
||||
class Assemble implements Workshop
|
||||
{
|
||||
|
||||
public function work()
|
||||
{
|
||||
print 'Assembled';
|
||||
}
|
||||
}
|
21
Structural/Bridge/BridgeTest.php
Normal file
21
Structural/Bridge/BridgeTest.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\Structural\Bridge;
|
||||
|
||||
class BridgeTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
public function testCar()
|
||||
{
|
||||
$vehicle = new Car(new Produce(), new Assemble());
|
||||
$this->expectOutputString('Car Produced Assembled');
|
||||
$vehicle->manufacture();
|
||||
}
|
||||
|
||||
public function testMotorcycle()
|
||||
{
|
||||
$vehicle = new Motorcycle(new Produce(), new Assemble());
|
||||
$this->expectOutputString('Motorcycle Produced Assembled');
|
||||
$vehicle->manufacture();
|
||||
}
|
||||
}
|
22
Structural/Bridge/Car.php
Normal file
22
Structural/Bridge/Car.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\Structural\Bridge;
|
||||
|
||||
/**
|
||||
* Refined Abstraction
|
||||
*/
|
||||
class Car extends Vehicle
|
||||
{
|
||||
|
||||
public function __construct(Workshop $workShop1, Workshop $workShop2)
|
||||
{
|
||||
parent::__construct($workShop1, $workShop2);
|
||||
}
|
||||
|
||||
public function manufacture()
|
||||
{
|
||||
print 'Car ';
|
||||
$this->workShop1->work();
|
||||
$this->workShop2->work();
|
||||
}
|
||||
}
|
22
Structural/Bridge/Motorcycle.php
Normal file
22
Structural/Bridge/Motorcycle.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\Structural\Bridge;
|
||||
|
||||
/**
|
||||
* Refined Abstraction
|
||||
*/
|
||||
class Motorcycle extends Vehicle
|
||||
{
|
||||
|
||||
public function __construct(Workshop $workShop1, Workshop $workShop2)
|
||||
{
|
||||
parent::__construct($workShop1, $workShop2);
|
||||
}
|
||||
|
||||
public function manufacture()
|
||||
{
|
||||
print 'Motorcycle ';
|
||||
$this->workShop1->work();
|
||||
$this->workShop2->work();
|
||||
}
|
||||
}
|
15
Structural/Bridge/Produce.php
Normal file
15
Structural/Bridge/Produce.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\Structural\Bridge;
|
||||
|
||||
/**
|
||||
* Concrete Implementation
|
||||
*/
|
||||
class Produce implements Workshop
|
||||
{
|
||||
|
||||
public function work()
|
||||
{
|
||||
print 'Produced ';
|
||||
}
|
||||
}
|
7
Structural/Bridge/README.md
Normal file
7
Structural/Bridge/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
## Purpose
|
||||
|
||||
Decouple an abstraction from its implementation so that the two can vary
|
||||
independently. (http://en.wikipedia.org/wiki/Bridge_pattern)
|
||||
|
||||
|
||||
|
23
Structural/Bridge/Vehicle.php
Normal file
23
Structural/Bridge/Vehicle.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\Structural\Bridge;
|
||||
|
||||
/**
|
||||
* Abstraction
|
||||
*/
|
||||
abstract class Vehicle
|
||||
{
|
||||
|
||||
protected $workShop1;
|
||||
protected $workShop2;
|
||||
|
||||
protected function __construct(Workshop $workShop1, Workshop $workShop2)
|
||||
{
|
||||
$this->workShop1 = $workShop1;
|
||||
$this->workShop2 = $workShop2;
|
||||
}
|
||||
|
||||
public function manufacture()
|
||||
{
|
||||
}
|
||||
}
|
12
Structural/Bridge/Workshop.php
Normal file
12
Structural/Bridge/Workshop.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\Structural\Bridge;
|
||||
|
||||
/**
|
||||
* Implementer
|
||||
*/
|
||||
interface Workshop
|
||||
{
|
||||
|
||||
public function work();
|
||||
}
|
@@ -5,6 +5,7 @@ ease the design by identifying a simple way to realize relationships between
|
||||
entities.
|
||||
|
||||
* [Adapter](Adapter) [:notebook:](http://en.wikipedia.org/wiki/Adapter_pattern)
|
||||
* [Bridge](Bridge) [:notebook:](http://en.wikipedia.org/wiki/Bridge_pattern)
|
||||
* [Composite](Composite) [:notebook:](http://en.wikipedia.org/wiki/Composite_pattern)
|
||||
* [DataMapper](DataMapper) [:notebook:](http://en.wikipedia.org/wiki/Data_mapper_pattern)
|
||||
* [Decorator](Decorator) [:notebook:](http://en.wikipedia.org/wiki/Decorator_pattern)
|
||||
|
Reference in New Issue
Block a user