This commit is contained in:
Dominik Liebler 2013-09-21 22:25:20 +02:00
parent 9484868299
commit f6651bafaa
9 changed files with 56 additions and 173 deletions

View File

@ -7,7 +7,17 @@ namespace DesignPatterns\Adapter;
*/
interface EBookInterface
{
function pressNext();
/**
* go to next page
*
* @return mixed
*/
public function pressNext();
function pressStart();
}
/**
* start the book
*
* @return mixed
*/
public function pressStart();
}

View File

@ -5,35 +5,51 @@ namespace DesignPatterns\Builder;
/**
* BikeBuilder builds bike
*/
class BikeBuilder implements Builder
class BikeBuilder implements BuilderInterface
{
/**
* @var Parts\Bike
*/
protected $bike;
/**
* {@inheritdoc}
*/
public function addDoors()
{
}
/**
* {@inheritdoc}
*/
public function addEngine()
{
$this->bike->setPart('engine', new Parts\Engine());
}
/**
* {@inheritdoc}
*/
public function addWheel()
{
$this->bike->setPart('forwardWheel', new Parts\Wheel());
$this->bike->setPart('rearWheel', new Parts\Wheel());
}
/**
* {@inheritdoc}
*/
public function createVehicle()
{
$this->bike = new Parts\Bike();
}
/**
* {@inheritdoc}
*/
public function getVehicle()
{
return $this->bike;
}
}
}

View File

@ -14,7 +14,7 @@ namespace DesignPatterns\Builder;
* Note: Builders have often a fluent interface, see the mock builder of
* PHPUnit for example.
*/
interface Builder
interface BuilderInterface
{
/**
* @return mixed

View File

@ -5,7 +5,7 @@ namespace DesignPatterns\Builder;
/**
* CarBuilder builds car
*/
class CarBuilder implements Builder
class CarBuilder implements BuilderInterface
{
/**
* @var Parts\Car

View File

@ -14,8 +14,12 @@ class Director
/**
* The director don't know 'bout concrete part
*
* @param BuilderInterface $builder
*
* @return Parts\Vehicle
*/
public function build(Builder $builder)
public function build(BuilderInterface $builder)
{
$builder->createVehicle();
$builder->addDoors();
@ -24,5 +28,4 @@ class Director
return $builder->getVehicle();
}
}
}

View File

@ -1,96 +0,0 @@
<?php
namespace DesignPatterns;
/**
* chain of responsibilities pattern
*
* Purpose:
* to build a chain of objects to handle a call. if one object cannot handle a call, it delegates the call to the next
* in the chain and so forth
*
* Examples:
* - logging framework
* - spam filter
* - Caching: first object is an instance of e.g. a Memcached Interface, if that "misses" it delegates the call to the
* Database Interface
* - Yii Framework: CFilterChain is a chain of controller action filters. the executing point is passed from one filter
* to the next along the chain, and only if all filters say "yes", the action can be invoked at last.
*
*/
// the idea is good but in general, the Handler component in this pattern
// is an abstract class which makes much more of the work
interface KeyValueStorage
{
public function get($key);
}
class SlowStorage implements KeyValueStorage
{
protected $_data = array();
public function __construct($data = array())
{
$this->_data = $data;
}
/**
* this class has no next handler, so it MUST be able to handle all requests
*
* @param $key
* @return mixed
*/
public function get($key)
{
return $this->_data[$key];
}
}
class FastStorage implements KeyValueStorage
{
/**
* @var array
*/
protected $_data;
/**
* the next handler in the chain
*
* @var \DesignPatterns\KeyValueStorage
*/
protected $_nextHandler;
public function __construct(array $data, KeyValueStorage $nextHandler)
{
$this->_data = $data;
$this->_nextHandler = $nextHandler;
}
/**
* when this storage gets a "miss", search in next handler
*
* @param $key
* @return mixed
*/
public function get($key)
{
if (true /* miss */) {
// delegate the call to the next handler in the chain
return $this->_nextHandler->get($key);
}
}
}
// BUILD THE STORAGES AND CHAIN
$slowStorage = new SlowStorage(array('foo' => 'bar'));
$fastStorage = new FastStorage(array('bar' => 'baz'), $slowStorage);
$fastStorage->get('foo'); // will be handled by SlowStorage
$fastStorage->get('bar'); // will be handled by FastStorage
/**
* In this example we could also add a abstract class and extend it to build Fast- and SlowStorage. That class would
* then manage the chain and when the cache hits a "miss", it would check if there is a next handler
*/

View File

@ -0,0 +1,13 @@
# chain of responsibilities
## Purpose:
To build a chain of objects to handle a call. if one object cannot handle a call, it delegates the call to the next
in the chain and so forth
## Examples:
* logging framework
* spam filter
Caching: first object is an instance of e.g. a Memcached Interface, if that "misses" it delegates the call to the database interface
* Yii Framework: CFilterChain is a chain of controller action filters. the executing point is passed from one filter to the next along the chain, and only if all filters say "yes", the action can be invoked at last.

View File

@ -33,7 +33,7 @@ class DirectorTest extends \PHPUnit_Framework_TestCase
*
* @dataProvider getBuilder
*/
public function testBuild(\DesignPatterns\Builder\Builder $builder)
public function testBuild(\DesignPatterns\Builder\BuilderInterface $builder)
{
$newVehicle = $this->director->build($builder);
$this->assertInstanceOf('DesignPatterns\Builder\Parts\Vehicle', $newVehicle);

View File

@ -1,63 +0,0 @@
<?php
namespace DesignPatterns\Tests\Iterator;
use DesignPatterns\Iterator\CardGame;
/**
* IteratorTest tests the CardGame iterator
*/
class IteratorTest extends \PHPUnit_Framework_TestCase
{
protected $deck;
protected function setUp()
{
$this->deck = new CardGame();
}
/**
* This is the client of the iterator.
* It remains unchanged even if one day I decide to use MongoDB to store the
* card.
*/
public function testCardinal()
{
$counter = 0;
foreach ($this->deck as $key => $card) {
$counter++;
}
$this->assertEquals(32, $counter);
}
/**
* Some fancy functions of PHP.
*/
public function testExampleOf_PHP_Helper()
{
// PHPUnit works on array or iterator :
$this->assertCount(32, $this->deck);
// a easy way to get an array from interator :
$cards = iterator_to_array($this->deck);
$this->assertEquals('A of S', $cards['SA']);
// a easy way to get an iterator from an array :
$iterator = new \ArrayIterator($cards);
$this->assertInstanceOf('\Iterator', $iterator);
}
/**
* Iterator can be combine, chained, filter, there are many in the SPL
* and sadly they are rarely used.
*/
public function testIteratorCombining()
{
// a fancy way to add a joker to the deck :
$joker = array('JK' => 'Joker');
$newDeck = new \AppendIterator();
$newDeck->append($this->deck);
$newDeck->append(new \ArrayIterator($joker));
$this->assertCount(33, $newDeck);
}
}