Merge branch 'master' of github.com:domnikl/DesignPatternsPHP

This commit is contained in:
Leonam Pereira Dias
2016-03-13 14:24:17 -03:00
234 changed files with 3852 additions and 1023 deletions

3
.gitignore vendored
View File

@@ -4,3 +4,6 @@
/vendor/ /vendor/
_build/ _build/
*.mo *.mo
.vagrant/
phpunit.xml
composer.phar

View File

@@ -20,8 +20,11 @@ cache:
directories: directories:
- $HOME/.composer/cache - $HOME/.composer/cache
before_script: before_install:
- composer self-update - composer self-update
- composer validate
install:
- composer install --prefer-dist --no-interaction - composer install --prefer-dist --no-interaction
script: script:

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Behavioral\ChainOfResponsibilities; namespace DesignPatterns\Behavioral\ChainOfResponsibilities;
/** /**
* Handler is a generic handler in the chain of responsibilities * Handler is a generic handler in the chain of responsibilities.
* *
* Yes you could have a lighter CoR with a simpler handler but if you want your CoR * Yes you could have a lighter CoR with a simpler handler but if you want your CoR
* to be extendable and decoupled, it's a better idea to do things like that in real * to be extendable and decoupled, it's a better idea to do things like that in real
@@ -18,7 +18,7 @@ abstract class Handler
private $successor = null; private $successor = null;
/** /**
* Append a responsibility to the end of chain * Append a responsibility to the end of chain.
* *
* A prepend method could be done with the same spirit * A prepend method could be done with the same spirit
* *
@@ -68,7 +68,7 @@ abstract class Handler
} }
/** /**
* Each concrete handler has to implement the processing of the request * Each concrete handler has to implement the processing of the request.
* *
* @param Request $req * @param Request $req
* *

View File

@@ -6,7 +6,7 @@ use DesignPatterns\Behavioral\ChainOfResponsibilities\Handler;
use DesignPatterns\Behavioral\ChainOfResponsibilities\Request; use DesignPatterns\Behavioral\ChainOfResponsibilities\Request;
/** /**
* Class FastStorage * Class FastStorage.
*/ */
class FastStorage extends Handler class FastStorage extends Handler
{ {

View File

@@ -6,14 +6,13 @@ use DesignPatterns\Behavioral\ChainOfResponsibilities\Handler;
use DesignPatterns\Behavioral\ChainOfResponsibilities\Request; use DesignPatterns\Behavioral\ChainOfResponsibilities\Request;
/** /**
* This is mostly the same code as FastStorage but in fact, it may greatly differs * This is mostly the same code as FastStorage but in fact, it may greatly differs.
* *
* One important fact about CoR: each item in the chain MUST NOT assume its position * One important fact about CoR: each item in the chain MUST NOT assume its position
* in the chain. A CoR is not responsible if the request is not handled UNLESS * in the chain. A CoR is not responsible if the request is not handled UNLESS
* you make an "ExceptionHandler" which throws execption if the request goes there. * you make an "ExceptionHandler" which throws exception if the request goes there.
* *
* To be really extendable, each handler doesn't know if there is something after it. * To be really extendable, each handler doesn't know if there is something after it.
*
*/ */
class SlowStorage extends Handler class SlowStorage extends Handler
{ {

View File

@@ -3,16 +3,15 @@
namespace DesignPatterns\Behavioral\ChainOfResponsibilities\Tests; namespace DesignPatterns\Behavioral\ChainOfResponsibilities\Tests;
use DesignPatterns\Behavioral\ChainOfResponsibilities\Request; use DesignPatterns\Behavioral\ChainOfResponsibilities\Request;
use DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible;
use DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible\FastStorage; use DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible\FastStorage;
use DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible\SlowStorage; use DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible\SlowStorage;
use DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible;
/** /**
* ChainTest tests the CoR * ChainTest tests the CoR.
*/ */
class ChainTest extends \PHPUnit_Framework_TestCase class ChainTest extends \PHPUnit_Framework_TestCase
{ {
/** /**
* @var FastStorage * @var FastStorage
*/ */
@@ -30,7 +29,7 @@ class ChainTest extends \PHPUnit_Framework_TestCase
$request->verb = 'get'; $request->verb = 'get';
return array( return array(
array($request) array($request),
); );
} }

View File

@@ -0,0 +1,46 @@
<?php
namespace DesignPatterns\Behavioral\Command;
/**
* This concrete command tweaks receiver to add current date to messages
* invoker just knows that it can call "execute".
*/
class AddMessageDateCommand implements UndoableCommandInterface
{
/**
* @var Receiver
*/
protected $output;
/**
* Each concrete command is built with different receivers.
* There can be one, many or completely no receivers, but there can be other commands in the parameters.
*
* @param Receiver $console
*/
public function __construct(Receiver $console)
{
$this->output = $console;
}
/**
* Execute and make receiver to enable displaying messages date.
*/
public function execute()
{
// sometimes, there is no receiver and this is the command which
// does all the work
$this->output->enableDate();
}
/**
* Undo the command and make receiver to disable displaying messages date.
*/
public function undo()
{
// sometimes, there is no receiver and this is the command which
// does all the work
$this->output->disableDate();
}
}

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Behavioral\Command; namespace DesignPatterns\Behavioral\Command;
/** /**
* class CommandInterface * class CommandInterface.
*/ */
interface CommandInterface interface CommandInterface
{ {

View File

@@ -4,7 +4,7 @@ namespace DesignPatterns\Behavioral\Command;
/** /**
* This concrete command calls "print" on the Receiver, but an external * This concrete command calls "print" on the Receiver, but an external
* invoker just know he can call "execute" * invoker just knows that it can call "execute".
*/ */
class HelloCommand implements CommandInterface class HelloCommand implements CommandInterface
{ {
@@ -14,8 +14,8 @@ class HelloCommand implements CommandInterface
protected $output; protected $output;
/** /**
* Each concrete command is builded with different receivers. * Each concrete command is built with different receivers.
* Can be one, many, none or even other Command in parameters * There can be one, many or completely no receivers, but there can be other commands in the parameters.
* *
* @param Receiver $console * @param Receiver $console
*/ */
@@ -25,7 +25,7 @@ class HelloCommand implements CommandInterface
} }
/** /**
* execute and output "Hello World" * execute and output "Hello World".
*/ */
public function execute() public function execute()
{ {

View File

@@ -4,7 +4,7 @@ namespace DesignPatterns\Behavioral\Command;
/** /**
* Invoker is using the command given to it. * Invoker is using the command given to it.
* Example : an Application in SF2 * Example : an Application in SF2.
*/ */
class Invoker class Invoker
{ {
@@ -25,7 +25,7 @@ class Invoker
} }
/** /**
* executes the command * executes the command.
*/ */
public function run() public function run()
{ {

View File

@@ -3,15 +3,44 @@
namespace DesignPatterns\Behavioral\Command; namespace DesignPatterns\Behavioral\Command;
/** /**
* Receiver is specific service with its own contract and can be only concrete * Receiver is specific service with its own contract and can be only concrete.
*/ */
class Receiver class Receiver
{ {
private $enableDate = false;
private $output = array();
/** /**
* @param string $str * @param string $str
*/ */
public function write($str) public function write($str)
{ {
echo $str; if ($this->enableDate) {
$str .= ' ['.date('Y-m-d').']';
}
$this->output[] = $str;
}
public function getOutput()
{
return implode("\n", $this->output);
}
/**
* Enable receiver to display message date.
*/
public function enableDate()
{
$this->enableDate = true;
}
/**
* Disable receiver to display message date.
*/
public function disableDate()
{
$this->enableDate = false;
} }
} }

View File

@@ -2,16 +2,15 @@
namespace DesignPatterns\Behavioral\Command\Tests; namespace DesignPatterns\Behavioral\Command\Tests;
use DesignPatterns\Behavioral\Command\HelloCommand;
use DesignPatterns\Behavioral\Command\Invoker; use DesignPatterns\Behavioral\Command\Invoker;
use DesignPatterns\Behavioral\Command\Receiver; use DesignPatterns\Behavioral\Command\Receiver;
use DesignPatterns\Behavioral\Command\HelloCommand;
/** /**
* CommandTest has the role of the Client in the Command Pattern * CommandTest has the role of the Client in the Command Pattern.
*/ */
class CommandTest extends \PHPUnit_Framework_TestCase class CommandTest extends \PHPUnit_Framework_TestCase
{ {
/** /**
* @var Invoker * @var Invoker
*/ */
@@ -31,7 +30,7 @@ class CommandTest extends \PHPUnit_Framework_TestCase
public function testInvocation() public function testInvocation()
{ {
$this->invoker->setCommand(new HelloCommand($this->receiver)); $this->invoker->setCommand(new HelloCommand($this->receiver));
$this->expectOutputString('Hello World');
$this->invoker->run(); $this->invoker->run();
$this->assertEquals($this->receiver->getOutput(), 'Hello World');
} }
} }

View File

@@ -0,0 +1,49 @@
<?php
namespace DesignPatterns\Behavioral\Command\Tests;
use DesignPatterns\Behavioral\Command\AddMessageDateCommand;
use DesignPatterns\Behavioral\Command\HelloCommand;
use DesignPatterns\Behavioral\Command\Invoker;
use DesignPatterns\Behavioral\Command\Receiver;
use PHPUnit_Framework_TestCase;
/**
* UndoableCommandTest has the role of the Client in the Command Pattern.
*/
class UndoableCommandTest extends PHPUnit_Framework_TestCase
{
/**
* @var Invoker
*/
protected $invoker;
/**
* @var Receiver
*/
protected $receiver;
protected function setUp()
{
$this->invoker = new Invoker();
$this->receiver = new Receiver();
}
public function testInvocation()
{
$this->invoker->setCommand(new HelloCommand($this->receiver));
$this->invoker->run();
$this->assertEquals($this->receiver->getOutput(), 'Hello World');
$messageDateCommand = new AddMessageDateCommand($this->receiver);
$messageDateCommand->execute();
$this->invoker->run();
$this->assertEquals($this->receiver->getOutput(), "Hello World\nHello World [".date('Y-m-d').']');
$messageDateCommand->undo();
$this->invoker->run();
$this->assertEquals($this->receiver->getOutput(), "Hello World\nHello World [".date('Y-m-d')."]\nHello World");
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace DesignPatterns\Behavioral\Command;
/**
* Interface UndoableCommandInterface.
*/
interface UndoableCommandInterface extends CommandInterface
{
/**
* This method is used to undo change made by command execution
* The Receiver goes in the constructor.
*/
public function undo();
}

View File

@@ -4,7 +4,6 @@ namespace DesignPatterns\Behavioral\Iterator;
class Book class Book
{ {
private $author; private $author;
private $title; private $title;
@@ -27,6 +26,6 @@ class Book
public function getAuthorAndTitle() public function getAuthorAndTitle()
{ {
return $this->getTitle() . ' by ' . $this->getAuthor(); return $this->getTitle().' by '.$this->getAuthor();
} }
} }

View File

@@ -4,23 +4,20 @@ namespace DesignPatterns\Behavioral\Iterator;
class BookList implements \Countable class BookList implements \Countable
{ {
private $books; private $books;
public function getBook($bookNumberToGet) public function getBook($bookNumberToGet)
{ {
if ((int)$bookNumberToGet <= $this->count()) { if (isset($this->books[$bookNumberToGet])) {
return $this->books[$bookNumberToGet]; return $this->books[$bookNumberToGet];
} }
return null; return;
} }
public function addBook(Book $book) public function addBook(Book $book)
{ {
$this->books[] = $book; $this->books[] = $book;
return $this->count();
} }
public function removeBook(Book $bookToRemove) public function removeBook(Book $bookToRemove)
@@ -31,8 +28,6 @@ class BookList implements \Countable
unset($this->books[$key]); unset($this->books[$key]);
} }
} }
return $this->count();
} }
public function count() public function count()

View File

@@ -4,11 +4,10 @@ namespace DesignPatterns\Behavioral\Iterator;
class BookListIterator implements \Iterator class BookListIterator implements \Iterator
{ {
/** /**
* @var BookList * @var BookList
*/ */
protected $bookList; private $bookList;
/** /**
* @var int * @var int
@@ -21,8 +20,10 @@ class BookListIterator implements \Iterator
} }
/** /**
* Return the current book * Return the current book.
*
* @link http://php.net/manual/en/iterator.current.php * @link http://php.net/manual/en/iterator.current.php
*
* @return Book Can return any type. * @return Book Can return any type.
*/ */
public function current() public function current()
@@ -32,8 +33,10 @@ class BookListIterator implements \Iterator
/** /**
* (PHP 5 &gt;= 5.0.0)<br/> * (PHP 5 &gt;= 5.0.0)<br/>
* Move forward to next element * Move forward to next element.
*
* @link http://php.net/manual/en/iterator.next.php * @link http://php.net/manual/en/iterator.next.php
*
* @return void Any returned value is ignored. * @return void Any returned value is ignored.
*/ */
public function next() public function next()
@@ -43,8 +46,10 @@ class BookListIterator implements \Iterator
/** /**
* (PHP 5 &gt;= 5.0.0)<br/> * (PHP 5 &gt;= 5.0.0)<br/>
* Return the key of the current element * Return the key of the current element.
*
* @link http://php.net/manual/en/iterator.key.php * @link http://php.net/manual/en/iterator.key.php
*
* @return mixed scalar on success, or null on failure. * @return mixed scalar on success, or null on failure.
*/ */
public function key() public function key()
@@ -54,20 +59,24 @@ class BookListIterator implements \Iterator
/** /**
* (PHP 5 &gt;= 5.0.0)<br/> * (PHP 5 &gt;= 5.0.0)<br/>
* Checks if current position is valid * Checks if current position is valid.
*
* @link http://php.net/manual/en/iterator.valid.php * @link http://php.net/manual/en/iterator.valid.php
* @return boolean The return value will be casted to boolean and then evaluated. *
* Returns true on success or false on failure. * @return bool The return value will be casted to boolean and then evaluated.
* Returns true on success or false on failure.
*/ */
public function valid() public function valid()
{ {
return $this->currentBook < $this->bookList->count(); return null !== $this->bookList->getBook($this->currentBook);
} }
/** /**
* (PHP 5 &gt;= 5.0.0)<br/> * (PHP 5 &gt;= 5.0.0)<br/>
* Rewind the Iterator to the first element * Rewind the Iterator to the first element.
*
* @link http://php.net/manual/en/iterator.rewind.php * @link http://php.net/manual/en/iterator.rewind.php
*
* @return void Any returned value is ignored. * @return void Any returned value is ignored.
*/ */
public function rewind() public function rewind()

View File

@@ -2,8 +2,17 @@
namespace DesignPatterns\Behavioral\Iterator; namespace DesignPatterns\Behavioral\Iterator;
class BookListReverseIterator extends BookListIterator class BookListReverseIterator implements \Iterator
{ {
/**
* @var BookList
*/
private $bookList;
/**
* @var int
*/
protected $currentBook = 0;
public function __construct(BookList $bookList) public function __construct(BookList $bookList)
{ {
@@ -11,13 +20,68 @@ class BookListReverseIterator extends BookListIterator
$this->currentBook = $this->bookList->count() - 1; $this->currentBook = $this->bookList->count() - 1;
} }
/**
* Return the current book.
*
* @link http://php.net/manual/en/iterator.current.php
*
* @return Book Can return any type.
*/
public function current()
{
return $this->bookList->getBook($this->currentBook);
}
/**
* (PHP 5 &gt;= 5.0.0)<br/>
* Move forward to next element.
*
* @link http://php.net/manual/en/iterator.next.php
*
* @return void Any returned value is ignored.
*/
public function next() public function next()
{ {
$this->currentBook--; $this->currentBook--;
} }
/**
* (PHP 5 &gt;= 5.0.0)<br/>
* Return the key of the current element.
*
* @link http://php.net/manual/en/iterator.key.php
*
* @return mixed scalar on success, or null on failure.
*/
public function key()
{
return $this->currentBook;
}
/**
* (PHP 5 &gt;= 5.0.0)<br/>
* Checks if current position is valid.
*
* @link http://php.net/manual/en/iterator.valid.php
*
* @return bool The return value will be casted to boolean and then evaluated.
* Returns true on success or false on failure.
*/
public function valid() public function valid()
{ {
return 0 <= $this->currentBook; return null !== $this->bookList->getBook($this->currentBook);
}
/**
* (PHP 5 &gt;= 5.0.0)<br/>
* Rewind the Iterator to the first element.
*
* @link http://php.net/manual/en/iterator.rewind.php
*
* @return void Any returned value is ignored.
*/
public function rewind()
{
$this->currentBook = $this->bookList->count() - 1;
} }
} }

View File

@@ -9,7 +9,6 @@ use DesignPatterns\Behavioral\Iterator\BookListReverseIterator;
class IteratorTest extends \PHPUnit_Framework_TestCase class IteratorTest extends \PHPUnit_Framework_TestCase
{ {
/** /**
* @var BookList * @var BookList
*/ */
@@ -30,8 +29,8 @@ class IteratorTest extends \PHPUnit_Framework_TestCase
array( array(
'Learning PHP Design Patterns by William Sanders', 'Learning PHP Design Patterns by William Sanders',
'Professional Php Design Patterns by Aaron Saray', 'Professional Php Design Patterns by Aaron Saray',
'Clean Code by Robert C. Martin' 'Clean Code by Robert C. Martin',
) ),
), ),
); );
} }
@@ -65,7 +64,7 @@ class IteratorTest extends \PHPUnit_Framework_TestCase
} }
/** /**
* Test BookList Remove * Test BookList Remove.
*/ */
public function testBookRemove() public function testBookRemove()
{ {

View File

@@ -9,12 +9,12 @@ namespace DesignPatterns\Behavioral\Mediator;
abstract class Colleague abstract class Colleague
{ {
/** /**
* this ensures no change in subclasses * this ensures no change in subclasses.
* *
* @var MediatorInterface * @var MediatorInterface
*/ */
private $mediator; private $mediator;
/** /**
* @param MediatorInterface $medium * @param MediatorInterface $medium
*/ */
@@ -25,6 +25,7 @@ abstract class Colleague
} }
// for subclasses // for subclasses
protected function getMediator() protected function getMediator()
{ {
return $this->mediator; return $this->mediator;

View File

@@ -2,15 +2,12 @@
namespace DesignPatterns\Behavioral\Mediator; namespace DesignPatterns\Behavioral\Mediator;
use DesignPatterns\Behavioral\Mediator\Subsystem;
/** /**
* Mediator is the concrete Mediator for this design pattern. * Mediator is the concrete Mediator for this design pattern.
* In this example, I have made a "Hello World" with the Mediator Pattern. * In this example, I have made a "Hello World" with the Mediator Pattern.
*/ */
class Mediator implements MediatorInterface class Mediator implements MediatorInterface
{ {
/** /**
* @var Subsystem\Server * @var Subsystem\Server
*/ */
@@ -39,7 +36,7 @@ class Mediator implements MediatorInterface
} }
/** /**
* make request * make request.
*/ */
public function makeRequest() public function makeRequest()
{ {
@@ -47,7 +44,8 @@ class Mediator implements MediatorInterface
} }
/** /**
* query db * query db.
*
* @return mixed * @return mixed
*/ */
public function queryDb() public function queryDb()
@@ -56,7 +54,7 @@ class Mediator implements MediatorInterface
} }
/** /**
* send response * send response.
* *
* @param string $content * @param string $content
*/ */

View File

@@ -4,24 +4,24 @@ namespace DesignPatterns\Behavioral\Mediator;
/** /**
* MediatorInterface is a contract for the Mediator * MediatorInterface is a contract for the Mediator
* This interface is not mandatory but it is better for LSP concerns * This interface is not mandatory but it is better for LSP concerns.
*/ */
interface MediatorInterface interface MediatorInterface
{ {
/** /**
* sends the response * sends the response.
* *
* @param string $content * @param string $content
*/ */
public function sendResponse($content); public function sendResponse($content);
/** /**
* makes a request * makes a request.
*/ */
public function makeRequest(); public function makeRequest();
/** /**
* queries the DB * queries the DB.
*/ */
public function queryDb(); public function queryDb();
} }

View File

@@ -4,8 +4,8 @@
Purpose Purpose
------- -------
This pattern provides an easy to decouple many components working This pattern provides an easy way to decouple many components working
together. It is a good alternative over Observer IF you have a "central together. It is a good alternative to Observer IF you have a "central
intelligence", like a controller (but not in the sense of the MVC). intelligence", like a controller (but not in the sense of the MVC).
All components (called Colleague) are only coupled to the All components (called Colleague) are only coupled to the
@@ -70,4 +70,4 @@ Tests/MediatorTest.php
:linenos: :linenos:
.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Behavioral/Mediator .. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Behavioral/Mediator
.. __: http://en.wikipedia.org/wiki/Mediator_pattern .. __: http://en.wikipedia.org/wiki/Mediator_pattern

View File

@@ -5,12 +5,12 @@ namespace DesignPatterns\Behavioral\Mediator\Subsystem;
use DesignPatterns\Behavioral\Mediator\Colleague; use DesignPatterns\Behavioral\Mediator\Colleague;
/** /**
* Client is a client that make request et get response * Client is a client that make request et get response.
*/ */
class Client extends Colleague class Client extends Colleague
{ {
/** /**
* request * request.
*/ */
public function request() public function request()
{ {
@@ -18,7 +18,7 @@ class Client extends Colleague
} }
/** /**
* output content * output content.
* *
* @param string $content * @param string $content
*/ */

View File

@@ -5,7 +5,7 @@ namespace DesignPatterns\Behavioral\Mediator\Subsystem;
use DesignPatterns\Behavioral\Mediator\Colleague; use DesignPatterns\Behavioral\Mediator\Colleague;
/** /**
* Database is a database service * Database is a database service.
*/ */
class Database extends Colleague class Database extends Colleague
{ {
@@ -14,6 +14,6 @@ class Database extends Colleague
*/ */
public function getData() public function getData()
{ {
return "World"; return 'World';
} }
} }

View File

@@ -5,12 +5,12 @@ namespace DesignPatterns\Behavioral\Mediator\Subsystem;
use DesignPatterns\Behavioral\Mediator\Colleague; use DesignPatterns\Behavioral\Mediator\Colleague;
/** /**
* Server serves responses * Server serves responses.
*/ */
class Server extends Colleague class Server extends Colleague
{ {
/** /**
* process on server * process on server.
*/ */
public function process() public function process()
{ {

View File

@@ -3,16 +3,15 @@
namespace DesignPatterns\Tests\Mediator\Tests; namespace DesignPatterns\Tests\Mediator\Tests;
use DesignPatterns\Behavioral\Mediator\Mediator; use DesignPatterns\Behavioral\Mediator\Mediator;
use DesignPatterns\Behavioral\Mediator\Subsystem\Database;
use DesignPatterns\Behavioral\Mediator\Subsystem\Client; use DesignPatterns\Behavioral\Mediator\Subsystem\Client;
use DesignPatterns\Behavioral\Mediator\Subsystem\Database;
use DesignPatterns\Behavioral\Mediator\Subsystem\Server; use DesignPatterns\Behavioral\Mediator\Subsystem\Server;
/** /**
* MediatorTest tests hello world * MediatorTest tests hello world.
*/ */
class MediatorTest extends \PHPUnit_Framework_TestCase class MediatorTest extends \PHPUnit_Framework_TestCase
{ {
protected $client; protected $client;
protected function setUp() protected function setUp()

View File

@@ -4,30 +4,46 @@ namespace DesignPatterns\Behavioral\Memento;
class Caretaker class Caretaker
{ {
public static function run() protected $history = array();
/**
* @return Memento
*/
public function getFromHistory($id)
{ {
/* @var $savedStates Memento[] */ return $this->history[$id];
}
$savedStates = array(); /**
* @param Memento $state
*/
public function saveToHistory(Memento $state)
{
$this->history[] = $state;
}
public function runCustomLogic()
{
$originator = new Originator(); $originator = new Originator();
//Setting state to State1 //Setting state to State1
$originator->setState("State1"); $originator->setState('State1');
//Setting state to State2 //Setting state to State2
$originator->setState("State2"); $originator->setState('State2');
//Saving State2 to Memento //Saving State2 to Memento
$savedStates[] = $originator->saveToMemento(); $this->saveToHistory($originator->getStateAsMemento());
//Setting state to State3 //Setting state to State3
$originator->setState("State3"); $originator->setState('State3');
// We can request multiple mementos, and choose which one to roll back to. // We can request multiple mementos, and choose which one to roll back to.
// Saving State3 to Memento // Saving State3 to Memento
$savedStates[] = $originator->saveToMemento(); $this->saveToHistory($originator->getStateAsMemento());
//Setting state to State4 //Setting state to State4
$originator->setState("State4"); $originator->setState('State4');
$originator->restoreFromMemento($savedStates[1]); $originator->restoreFromMemento($this->getFromHistory(1));
//State after restoring from Memento: State3 //State after restoring from Memento: State3
return $originator->getStateAsMemento()->getState();
} }
} }

View File

@@ -15,14 +15,17 @@ class Originator
*/ */
public function setState($state) public function setState($state)
{ {
// you must check type of state inside child of this class
// or use type-hinting for full pattern implementation
$this->state = $state; $this->state = $state;
} }
/** /**
* @return Memento * @return Memento
*/ */
public function saveToMemento() public function getStateAsMemento()
{ {
// you must save a separate copy in Memento
$state = is_object($this->state) ? clone $this->state : $this->state; $state = is_object($this->state) ? clone $this->state : $this->state;
return new Memento($state); return new Memento($state);

View File

@@ -4,26 +4,43 @@
Purpose Purpose
------- -------
Provide the ability to restore an object to its previous state (undo via It provides the ability to restore an object to it's previous state (undo
rollback). via rollback) or to gain access to state of the object, without revealing
it's implementation (i.e., the object is not required to have a functional
for return the current state).
The memento pattern is implemented with three objects: the originator, a The memento pattern is implemented with three objects: the Originator, a
caretaker and a memento. The originator is some object that has an Caretaker and a Memento.
internal state. The caretaker is going to do something to the
originator, but wants to be able to undo the change. The caretaker first Memento an object that *contains a concrete unique snapshot of state* of
asks the originator for a memento object. Then it does whatever any object or resource: string, number, array, an instance of class and so on.
operation (or sequence of operations) it was going to do. To roll back The uniqueness in this case does not imply the prohibition existence of similar
to the state before the operations, it returns the memento object to the states in different snapshots. That means the state can be extracted as
originator. The memento object itself is an opaque object (one which the the independent clone. Any object stored in the Memento should be
caretaker cannot, or should not, change). When using this pattern, care *a full copy of the original object rather than a reference* to the original
should be taken if the originator may change other objects or resources object. The Memento object is a "opaque object" (the object that no one can
- the memento pattern operates on a single object. or should change).
Originator it is an object that contains the *actual state of an external
object is strictly specified type*. Originator is able to create a unique
copy of this state and return it wrapped in a Memento. The Originator does
not know the history of changes. You can set a concrete state to Originator
from the outside, which will be considered as actual. The Originator must
make sure that given state corresponds the allowed type of object. Originator
may (but not should) have any methods, but they *they can't make changes to
the saved object state*.
Caretaker *controls the states history*. He may make changes to an object;
take a decision to save the state of an external object in the Originator;
ask from the Originator snapshot of the current state; or set the Originator
state to equivalence with some snapshot from history.
Examples Examples
-------- --------
- The seed of a pseudorandom number generator - The seed of a pseudorandom number generator
- The state in a finite state machine - The state in a finite state machine
- Control for intermediate states of `ORM Model <http://en.wikipedia.org/wiki/Object-relational_mapping>`_ before saving
UML Diagram UML Diagram
----------- -----------

View File

@@ -2,68 +2,161 @@
namespace DesignPatterns\Behavioral\Memento\Tests; namespace DesignPatterns\Behavioral\Memento\Tests;
use DesignPatterns\Behavioral\Memento\Caretaker;
use DesignPatterns\Behavioral\Memento\Memento;
use DesignPatterns\Behavioral\Memento\Originator; use DesignPatterns\Behavioral\Memento\Originator;
/** /**
* MementoTest tests the memento pattern * MementoTest tests the memento pattern.
*/ */
class MementoTest extends \PHPUnit_Framework_TestCase class MementoTest extends \PHPUnit_Framework_TestCase
{ {
public function testUsageExample()
{
$originator = new Originator();
$caretaker = new Caretaker();
$character = new \stdClass();
// new object
$character->name = 'Gandalf';
// connect Originator to character object
$originator->setState($character);
// work on the object
$character->name = 'Gandalf the Grey';
// still change something
$character->race = 'Maia';
// time to save state
$snapshot = $originator->getStateAsMemento();
// put state to log
$caretaker->saveToHistory($snapshot);
// change something
$character->name = 'Sauron';
// and again
$character->race = 'Ainur';
// state inside the Originator was equally changed
$this->assertAttributeEquals($character, 'state', $originator);
// time to save another state
$snapshot = $originator->getStateAsMemento();
// put state to log
$caretaker->saveToHistory($snapshot);
$rollback = $caretaker->getFromHistory(0);
// return to first state
$originator->restoreFromMemento($rollback);
// use character from old state
$character = $rollback->getState();
// yes, that what we need
$this->assertEquals('Gandalf the Grey', $character->name);
// make new changes
$character->name = 'Gandalf the White';
// and Originator linked to actual object again
$this->assertAttributeEquals($character, 'state', $originator);
}
public function testStringState() public function testStringState()
{ {
$originator = new Originator(); $originator = new Originator();
$originator->setState("State1"); $originator->setState('State1');
$this->assertAttributeEquals("State1", "state", $originator); $this->assertAttributeEquals('State1', 'state', $originator);
$originator->setState("State2"); $originator->setState('State2');
$this->assertAttributeEquals('State2', 'state', $originator);
$this->assertAttributeEquals("State2", "state", $originator); $snapshot = $originator->getStateAsMemento();
$this->assertAttributeEquals('State2', 'state', $snapshot);
$savedState = $originator->saveToMemento(); $originator->setState('State3');
$this->assertAttributeEquals('State3', 'state', $originator);
$this->assertAttributeEquals("State2", "state", $savedState); $originator->restoreFromMemento($snapshot);
$this->assertAttributeEquals('State2', 'state', $originator);
$originator->setState("State3");
$this->assertAttributeEquals("State3", "state", $originator);
$originator->restoreFromMemento($savedState);
$this->assertAttributeEquals("State2", "state", $originator);
} }
public function testObjectState() public function testSnapshotIsClone()
{
$originator = new Originator();
$object = new \stdClass();
$originator->setState($object);
$snapshot = $originator->getStateAsMemento();
$object->new_property = 1;
$this->assertAttributeEquals($object, 'state', $originator);
$this->assertAttributeNotEquals($object, 'state', $snapshot);
$originator->restoreFromMemento($snapshot);
$this->assertAttributeNotEquals($object, 'state', $originator);
}
public function testCanChangeActualState()
{
$originator = new Originator();
$first_state = new \stdClass();
$originator->setState($first_state);
$snapshot = $originator->getStateAsMemento();
$second_state = $snapshot->getState();
// still actual
$first_state->first_property = 1;
// just history
$second_state->second_property = 2;
$this->assertAttributeEquals($first_state, 'state', $originator);
$this->assertAttributeNotEquals($second_state, 'state', $originator);
$originator->restoreFromMemento($snapshot);
// now it lost state
$first_state->first_property = 11;
// must be actual
$second_state->second_property = 22;
$this->assertAttributeEquals($second_state, 'state', $originator);
$this->assertAttributeNotEquals($first_state, 'state', $originator);
}
public function testStateWithDifferentObjects()
{ {
$originator = new Originator(); $originator = new Originator();
$foo = new \stdClass(); $first = new \stdClass();
$foo->data = "foo"; $first->data = 'foo';
$originator->setState($foo); $originator->setState($first);
$this->assertAttributeEquals($first, 'state', $originator);
$this->assertAttributeEquals($foo, "state", $originator); $first_snapshot = $originator->getStateAsMemento();
$this->assertAttributeEquals($first, 'state', $first_snapshot);
$savedState = $originator->saveToMemento(); $second = new \stdClass();
$second->data = 'bar';
$originator->setState($second);
$this->assertAttributeEquals($second, 'state', $originator);
$this->assertAttributeEquals($foo, "state", $savedState); $originator->restoreFromMemento($first_snapshot);
$this->assertAttributeEquals($first, 'state', $originator);
}
$bar = new \stdClass(); public function testCaretaker()
$bar->data = "bar"; {
$caretaker = new Caretaker();
$memento1 = new Memento('foo');
$memento2 = new Memento('bar');
$caretaker->saveToHistory($memento1);
$caretaker->saveToHistory($memento2);
$this->assertAttributeEquals(array($memento1, $memento2), 'history', $caretaker);
$this->assertEquals($memento1, $caretaker->getFromHistory(0));
$this->assertEquals($memento2, $caretaker->getFromHistory(1));
}
$originator->setState($bar); public function testCaretakerCustomLogic()
{
$this->assertAttributeEquals($bar, "state", $originator); $caretaker = new Caretaker();
$result = $caretaker->runCustomLogic();
$originator->restoreFromMemento($savedState); $this->assertEquals('State3', $result);
$this->assertAttributeEquals($foo, "state", $originator);
$foo->data = null;
$this->assertAttributeNotEquals($foo, "state", $savedState);
$this->assertAttributeNotEquals($foo, "state", $originator);
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 61 KiB

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Behavioral\NullObject; namespace DesignPatterns\Behavioral\NullObject;
/** /**
* LoggerInterface is a contract for logging something * LoggerInterface is a contract for logging something.
* *
* Key feature: NullLogger MUST inherit from this interface like any other Loggers * Key feature: NullLogger MUST inherit from this interface like any other Loggers
*/ */

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Behavioral\NullObject; namespace DesignPatterns\Behavioral\NullObject;
/** /**
* PrintLogger is a logger that prints the log entry to standard output * PrintLogger is a logger that prints the log entry to standard output.
*/ */
class PrintLogger implements LoggerInterface class PrintLogger implements LoggerInterface
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Behavioral\NullObject; namespace DesignPatterns\Behavioral\NullObject;
/** /**
* Service is dummy service that uses a logger * Service is dummy service that uses a logger.
*/ */
class Service class Service
{ {
@@ -13,7 +13,7 @@ class Service
protected $logger; protected $logger;
/** /**
* we inject the logger in ctor and it is mandatory * we inject the logger in ctor and it is mandatory.
* *
* @param LoggerInterface $log * @param LoggerInterface $log
*/ */
@@ -28,7 +28,7 @@ class Service
public function doSomething() public function doSomething()
{ {
// no more check "if (!is_null($this->logger))..." with the NullObject pattern // no more check "if (!is_null($this->logger))..." with the NullObject pattern
$this->logger->log('We are in ' . __METHOD__); $this->logger->log('We are in '.__METHOD__);
// something to do... // something to do...
} }
} }

View File

@@ -3,15 +3,14 @@
namespace DesignPatterns\Behavioral\NullObject\Tests; namespace DesignPatterns\Behavioral\NullObject\Tests;
use DesignPatterns\Behavioral\NullObject\NullLogger; use DesignPatterns\Behavioral\NullObject\NullLogger;
use DesignPatterns\Behavioral\NullObject\Service;
use DesignPatterns\Behavioral\NullObject\PrintLogger; use DesignPatterns\Behavioral\NullObject\PrintLogger;
use DesignPatterns\Behavioral\NullObject\Service;
/** /**
* LoggerTest tests for different loggers * LoggerTest tests for different loggers.
*/ */
class LoggerTest extends \PHPUnit_Framework_TestCase class LoggerTest extends \PHPUnit_Framework_TestCase
{ {
public function testNullObject() public function testNullObject()
{ {
// one can use a singleton for NullObjet : I don't think it's a good idea // one can use a singleton for NullObjet : I don't think it's a good idea

View File

@@ -2,15 +2,14 @@
namespace DesignPatterns\Behavioral\Observer\Tests; namespace DesignPatterns\Behavioral\Observer\Tests;
use DesignPatterns\Behavioral\Observer\UserObserver;
use DesignPatterns\Behavioral\Observer\User; use DesignPatterns\Behavioral\Observer\User;
use DesignPatterns\Behavioral\Observer\UserObserver;
/** /**
* ObserverTest tests the Observer pattern * ObserverTest tests the Observer pattern.
*/ */
class ObserverTest extends \PHPUnit_Framework_TestCase class ObserverTest extends \PHPUnit_Framework_TestCase
{ {
protected $observer; protected $observer;
protected function setUp() protected function setUp()
@@ -19,7 +18,7 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
} }
/** /**
* Tests the notification * Tests the notification.
*/ */
public function testNotify() public function testNotify()
{ {
@@ -31,7 +30,7 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
} }
/** /**
* Tests the subscribing * Tests the subscribing.
*/ */
public function testAttachDetach() public function testAttachDetach()
{ {
@@ -53,7 +52,7 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
} }
/** /**
* Tests the update() invocation on a mockup * Tests the update() invocation on a mockup.
*/ */
public function testUpdateCalling() public function testUpdateCalling()
{ {

View File

@@ -3,34 +3,33 @@
namespace DesignPatterns\Behavioral\Observer; namespace DesignPatterns\Behavioral\Observer;
/** /**
* Observer pattern : The observed object (the subject) * Observer pattern : The observed object (the subject).
* *
* The subject maintains a list of Observers and sends notifications. * The subject maintains a list of Observers and sends notifications.
*
*/ */
class User implements \SplSubject class User implements \SplSubject
{ {
/** /**
* user data * user data.
* *
* @var array * @var array
*/ */
protected $data = array(); protected $data = array();
/** /**
* observers * observers.
* *
* @var \SplObjectStorage * @var \SplObjectStorage
*/ */
protected $observers; protected $observers;
public function __construct() public function __construct()
{ {
$this->observers = new \SplObjectStorage(); $this->observers = new \SplObjectStorage();
} }
/** /**
* attach a new observer * attach a new observer.
* *
* @param \SplObserver $observer * @param \SplObserver $observer
* *
@@ -42,7 +41,7 @@ class User implements \SplSubject
} }
/** /**
* detach an observer * detach an observer.
* *
* @param \SplObserver $observer * @param \SplObserver $observer
* *
@@ -54,7 +53,7 @@ class User implements \SplSubject
} }
/** /**
* notify observers * notify observers.
* *
* @return void * @return void
*/ */
@@ -68,7 +67,7 @@ class User implements \SplSubject
/** /**
* Ideally one would better write setter/getter for all valid attributes and only call notify() * Ideally one would better write setter/getter for all valid attributes and only call notify()
* on attributes that matter when changed * on attributes that matter when changed.
* *
* @param string $name * @param string $name
* @param mixed $value * @param mixed $value

View File

@@ -3,18 +3,18 @@
namespace DesignPatterns\Behavioral\Observer; namespace DesignPatterns\Behavioral\Observer;
/** /**
* class UserObserver * class UserObserver.
*/ */
class UserObserver implements \SplObserver class UserObserver implements \SplObserver
{ {
/** /**
* This is the only method to implement as an observer. * This is the only method to implement as an observer.
* It is called by the Subject (usually by SplSubject::notify() ) * It is called by the Subject (usually by SplSubject::notify() ).
* *
* @param \SplSubject $subject * @param \SplSubject $subject
*/ */
public function update(\SplSubject $subject) public function update(\SplSubject $subject)
{ {
echo get_class($subject) . ' has been updated'; echo get_class($subject).' has been updated';
} }
} }

View File

@@ -9,7 +9,7 @@ communication.
* [Command](Command) [:notebook:](http://en.wikipedia.org/wiki/Command_pattern) * [Command](Command) [:notebook:](http://en.wikipedia.org/wiki/Command_pattern)
* [Iterator](Iterator) [:notebook:](http://en.wikipedia.org/wiki/Iterator_pattern) * [Iterator](Iterator) [:notebook:](http://en.wikipedia.org/wiki/Iterator_pattern)
* [Mediator](Mediator) [:notebook:](http://en.wikipedia.org/wiki/Mediator_pattern) * [Mediator](Mediator) [:notebook:](http://en.wikipedia.org/wiki/Mediator_pattern)
* [Memento](Behavioral/Memento) [:notebook:](http://en.wikipedia.org/wiki/Memento_pattern) * [Memento](Memento) [:notebook:](http://en.wikipedia.org/wiki/Memento_pattern)
* [NullObject](NullObject) [:notebook:](http://en.wikipedia.org/wiki/Null_Object_pattern) * [NullObject](NullObject) [:notebook:](http://en.wikipedia.org/wiki/Null_Object_pattern)
* [Observer](Observer) [:notebook:](http://en.wikipedia.org/wiki/Observer_pattern) * [Observer](Observer) [:notebook:](http://en.wikipedia.org/wiki/Observer_pattern)
* [Specification](Specification) [:notebook:](http://en.wikipedia.org/wiki/Specification_pattern) * [Specification](Specification) [:notebook:](http://en.wikipedia.org/wiki/Specification_pattern)

View File

@@ -1,13 +1,14 @@
<?php <?php
namespace DesignPatterns\Behavioral\Specification; namespace DesignPatterns\Behavioral\Specification;
/** /**
* An abstract specification allows the creation of wrapped specifications * An abstract specification allows the creation of wrapped specifications.
*/ */
abstract class AbstractSpecification implements SpecificationInterface abstract class AbstractSpecification implements SpecificationInterface
{ {
/** /**
* Checks if given item meets all criteria * Checks if given item meets all criteria.
* *
* @param Item $item * @param Item $item
* *
@@ -16,7 +17,7 @@ abstract class AbstractSpecification implements SpecificationInterface
abstract public function isSatisfiedBy(Item $item); abstract public function isSatisfiedBy(Item $item);
/** /**
* Creates a new logical AND specification * Creates a new logical AND specification.
* *
* @param SpecificationInterface $spec * @param SpecificationInterface $spec
* *
@@ -28,7 +29,7 @@ abstract class AbstractSpecification implements SpecificationInterface
} }
/** /**
* Creates a new logical OR composite specification * Creates a new logical OR composite specification.
* *
* @param SpecificationInterface $spec * @param SpecificationInterface $spec
* *
@@ -40,7 +41,7 @@ abstract class AbstractSpecification implements SpecificationInterface
} }
/** /**
* Creates a new logical NOT specification * Creates a new logical NOT specification.
* *
* @return SpecificationInterface * @return SpecificationInterface
*/ */

View File

@@ -1,17 +1,17 @@
<?php <?php
namespace DesignPatterns\Behavioral\Specification; namespace DesignPatterns\Behavioral\Specification;
/** /**
* A logical OR specification * A logical OR specification.
*/ */
class Either extends AbstractSpecification class Either extends AbstractSpecification
{ {
protected $left; protected $left;
protected $right; protected $right;
/** /**
* A composite wrapper of two specifications * A composite wrapper of two specifications.
* *
* @param SpecificationInterface $left * @param SpecificationInterface $left
* @param SpecificationInterface $right * @param SpecificationInterface $right
@@ -23,7 +23,7 @@ class Either extends AbstractSpecification
} }
/** /**
* Returns the evaluation of both wrapped specifications as a logical OR * Returns the evaluation of both wrapped specifications as a logical OR.
* *
* @param Item $item * @param Item $item
* *

View File

@@ -1,15 +1,16 @@
<?php <?php
namespace DesignPatterns\Behavioral\Specification; namespace DesignPatterns\Behavioral\Specification;
/** /**
* An trivial item * An trivial item.
*/ */
class Item class Item
{ {
protected $price; protected $price;
/** /**
* An item must have a price * An item must have a price.
* *
* @param int $price * @param int $price
*/ */
@@ -19,7 +20,7 @@ class Item
} }
/** /**
* Get the items price * Get the items price.
* *
* @return int * @return int
*/ */

View File

@@ -1,16 +1,16 @@
<?php <?php
namespace DesignPatterns\Behavioral\Specification; namespace DesignPatterns\Behavioral\Specification;
/** /**
* A logical Not specification * A logical Not specification.
*/ */
class Not extends AbstractSpecification class Not extends AbstractSpecification
{ {
protected $spec; protected $spec;
/** /**
* Creates a new specification wrapping another * Creates a new specification wrapping another.
* *
* @param SpecificationInterface $spec * @param SpecificationInterface $spec
*/ */
@@ -20,7 +20,7 @@ class Not extends AbstractSpecification
} }
/** /**
* Returns the negated result of the wrapped specification * Returns the negated result of the wrapped specification.
* *
* @param Item $item * @param Item $item
* *

View File

@@ -1,17 +1,17 @@
<?php <?php
namespace DesignPatterns\Behavioral\Specification; namespace DesignPatterns\Behavioral\Specification;
/** /**
* A logical AND specification * A logical AND specification.
*/ */
class Plus extends AbstractSpecification class Plus extends AbstractSpecification
{ {
protected $left; protected $left;
protected $right; protected $right;
/** /**
* Creation of a logical AND of two specifications * Creation of a logical AND of two specifications.
* *
* @param SpecificationInterface $left * @param SpecificationInterface $left
* @param SpecificationInterface $right * @param SpecificationInterface $right
@@ -23,7 +23,7 @@ class Plus extends AbstractSpecification
} }
/** /**
* Checks if the composite AND of specifications passes * Checks if the composite AND of specifications passes.
* *
* @param Item $item * @param Item $item
* *

View File

@@ -1,8 +1,9 @@
<?php <?php
namespace DesignPatterns\Behavioral\Specification; namespace DesignPatterns\Behavioral\Specification;
/** /**
* A specification to check an Item is priced between min and max * A specification to check an Item is priced between min and max.
*/ */
class PriceSpecification extends AbstractSpecification class PriceSpecification extends AbstractSpecification
{ {
@@ -10,7 +11,7 @@ class PriceSpecification extends AbstractSpecification
protected $minPrice; protected $minPrice;
/** /**
* Sets the optional maximum price * Sets the optional maximum price.
* *
* @param int $maxPrice * @param int $maxPrice
*/ */
@@ -20,7 +21,7 @@ class PriceSpecification extends AbstractSpecification
} }
/** /**
* Sets the optional minimum price * Sets the optional minimum price.
* *
* @param int $minPrice * @param int $minPrice
*/ */
@@ -30,7 +31,7 @@ class PriceSpecification extends AbstractSpecification
} }
/** /**
* Checks if Item price falls between bounds * Checks if Item price falls between bounds.
* *
* @param Item $item * @param Item $item
* *

View File

@@ -1,13 +1,14 @@
<?php <?php
namespace DesignPatterns\Behavioral\Specification; namespace DesignPatterns\Behavioral\Specification;
/** /**
* An interface for a specification * An interface for a specification.
*/ */
interface SpecificationInterface interface SpecificationInterface
{ {
/** /**
* A boolean evaluation indicating if the object meets the specification * A boolean evaluation indicating if the object meets the specification.
* *
* @param Item $item * @param Item $item
* *
@@ -16,21 +17,21 @@ interface SpecificationInterface
public function isSatisfiedBy(Item $item); public function isSatisfiedBy(Item $item);
/** /**
* Creates a logical AND specification * Creates a logical AND specification.
* *
* @param SpecificationInterface $spec * @param SpecificationInterface $spec
*/ */
public function plus(SpecificationInterface $spec); public function plus(SpecificationInterface $spec);
/** /**
* Creates a logical OR specification * Creates a logical OR specification.
* *
* @param SpecificationInterface $spec * @param SpecificationInterface $spec
*/ */
public function either(SpecificationInterface $spec); public function either(SpecificationInterface $spec);
/** /**
* Creates a logical not specification * Creates a logical not specification.
*/ */
public function not(); public function not();
} }

View File

@@ -2,11 +2,11 @@
namespace DesignPatterns\Behavioral\Specification\Tests; namespace DesignPatterns\Behavioral\Specification\Tests;
use DesignPatterns\Behavioral\Specification\PriceSpecification;
use DesignPatterns\Behavioral\Specification\Item; use DesignPatterns\Behavioral\Specification\Item;
use DesignPatterns\Behavioral\Specification\PriceSpecification;
/** /**
* SpecificationTest tests the specification pattern * SpecificationTest tests the specification pattern.
*/ */
class SpecificationTest extends \PHPUnit_Framework_TestCase class SpecificationTest extends \PHPUnit_Framework_TestCase
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Behavioral\State; namespace DesignPatterns\Behavioral\State;
/** /**
* Class CreateOrder * Class CreateOrder.
*/ */
class CreateOrder implements OrderInterface class CreateOrder implements OrderInterface
{ {
@@ -38,8 +38,9 @@ class CreateOrder implements OrderInterface
} }
/** /**
* @return mixed|void
* @throws \Exception * @throws \Exception
*
* @return mixed|void
*/ */
public function completeOrder() public function completeOrder()
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Behavioral\State; namespace DesignPatterns\Behavioral\State;
/** /**
* Class OrderController * Class OrderController.
*/ */
class OrderController class OrderController
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Behavioral\State; namespace DesignPatterns\Behavioral\State;
/** /**
* Class OrderFactory * Class OrderFactory.
*/ */
class OrderFactory class OrderFactory
{ {
@@ -15,8 +15,9 @@ class OrderFactory
/** /**
* @param int $id * @param int $id
* *
* @return CreateOrder|ShippingOrder
* @throws \Exception * @throws \Exception
*
* @return CreateOrder|ShippingOrder
*/ */
public static function getOrder($id) public static function getOrder($id)
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Behavioral\State; namespace DesignPatterns\Behavioral\State;
/** /**
* Class OrderInterface * Class OrderInterface.
*/ */
interface OrderInterface interface OrderInterface
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Behavioral\State; namespace DesignPatterns\Behavioral\State;
/** /**
* Class ShippingOrder * Class ShippingOrder.
*/ */
class ShippingOrder implements OrderInterface class ShippingOrder implements OrderInterface
{ {
@@ -26,8 +26,9 @@ class ShippingOrder implements OrderInterface
} }
/** /**
* @return mixed|void
* @throws \Exception * @throws \Exception
*
* @return mixed|void
*/ */
public function shipOrder() public function shipOrder()
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Behavioral\Strategy; namespace DesignPatterns\Behavioral\Strategy;
/** /**
* Class ComparatorInterface * Class ComparatorInterface.
*/ */
interface ComparatorInterface interface ComparatorInterface
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Behavioral\Strategy; namespace DesignPatterns\Behavioral\Strategy;
/** /**
* Class DateComparator * Class DateComparator.
*/ */
class DateComparator implements ComparatorInterface class DateComparator implements ComparatorInterface
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Behavioral\Strategy; namespace DesignPatterns\Behavioral\Strategy;
/** /**
* Class IdComparator * Class IdComparator.
*/ */
class IdComparator implements ComparatorInterface class IdComparator implements ComparatorInterface
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Behavioral\Strategy; namespace DesignPatterns\Behavioral\Strategy;
/** /**
* Class ObjectCollection * Class ObjectCollection.
*/ */
class ObjectCollection class ObjectCollection
{ {
@@ -31,7 +31,7 @@ class ObjectCollection
public function sort() public function sort()
{ {
if (!$this->comparator) { if (!$this->comparator) {
throw new \LogicException("Comparator is not set"); throw new \LogicException('Comparator is not set');
} }
$callback = array($this->comparator, 'compare'); $callback = array($this->comparator, 'compare');

View File

@@ -8,21 +8,20 @@ use DesignPatterns\Behavioral\Strategy\ObjectCollection;
use DesignPatterns\Behavioral\Strategy\Strategy; use DesignPatterns\Behavioral\Strategy\Strategy;
/** /**
* Tests for Strategy pattern * Tests for Strategy pattern.
*/ */
class StrategyTest extends \PHPUnit_Framework_TestCase class StrategyTest extends \PHPUnit_Framework_TestCase
{ {
public function getIdCollection() public function getIdCollection()
{ {
return array( return array(
array( array(
array(array('id' => 2), array('id' => 1), array('id' => 3)), array(array('id' => 2), array('id' => 1), array('id' => 3)),
array('id' => 1) array('id' => 1),
), ),
array( array(
array(array('id' => 3), array('id' => 2), array('id' => 1)), array(array('id' => 3), array('id' => 2), array('id' => 1)),
array('id' => 1) array('id' => 1),
), ),
); );
} }
@@ -32,11 +31,11 @@ class StrategyTest extends \PHPUnit_Framework_TestCase
return array( return array(
array( array(
array(array('date' => '2014-03-03'), array('date' => '2015-03-02'), array('date' => '2013-03-01')), array(array('date' => '2014-03-03'), array('date' => '2015-03-02'), array('date' => '2013-03-01')),
array('date' => '2013-03-01') array('date' => '2013-03-01'),
), ),
array( array(
array(array('date' => '2014-02-03'), array('date' => '2013-02-01'), array('date' => '2015-02-02')), array(array('date' => '2014-02-03'), array('date' => '2013-02-01'), array('date' => '2015-02-02')),
array('date' => '2013-02-01') array('date' => '2013-02-01'),
), ),
); );
} }

View File

@@ -3,12 +3,12 @@
namespace DesignPatterns\Behavioral\TemplateMethod; namespace DesignPatterns\Behavioral\TemplateMethod;
/** /**
* BeachJourney is vacation at the beach * BeachJourney is vacation at the beach.
*/ */
class BeachJourney extends Journey class BeachJourney extends Journey
{ {
/** /**
* prints what to do to enjoy your vacation * prints what to do to enjoy your vacation.
*/ */
protected function enjoyVacation() protected function enjoyVacation()
{ {

View File

@@ -3,12 +3,12 @@
namespace DesignPatterns\Behavioral\TemplateMethod; namespace DesignPatterns\Behavioral\TemplateMethod;
/** /**
* CityJourney is a journey in a city * CityJourney is a journey in a city.
*/ */
class CityJourney extends Journey class CityJourney extends Journey
{ {
/** /**
* prints what to do in your journey to enjoy vacation * prints what to do in your journey to enjoy vacation.
*/ */
protected function enjoyVacation() protected function enjoyVacation()
{ {

View File

@@ -23,7 +23,7 @@ abstract class Journey
} }
/** /**
* This method must be implemented, this is the key-feature of this pattern * This method must be implemented, this is the key-feature of this pattern.
*/ */
abstract protected function enjoyVacation(); abstract protected function enjoyVacation();
@@ -37,7 +37,7 @@ abstract class Journey
} }
/** /**
* This method will be unknown by subclasses (better) * This method will be unknown by subclasses (better).
*/ */
private function buyAFlight() private function buyAFlight()
{ {
@@ -46,7 +46,7 @@ abstract class Journey
/** /**
* Subclasses will get access to this method but cannot override it and * Subclasses will get access to this method but cannot override it and
* compromise this algorithm (warning : cause of cyclic dependencies) * compromise this algorithm (warning : cause of cyclic dependencies).
*/ */
final protected function takePlane() final protected function takePlane()
{ {

View File

@@ -5,11 +5,10 @@ namespace DesignPatterns\Behavioral\TemplateMethod\Tests;
use DesignPatterns\Behavioral\TemplateMethod; use DesignPatterns\Behavioral\TemplateMethod;
/** /**
* JourneyTest tests all journeys * JourneyTest tests all journeys.
*/ */
class JourneyTest extends \PHPUnit_Framework_TestCase class JourneyTest extends \PHPUnit_Framework_TestCase
{ {
public function testBeach() public function testBeach()
{ {
$journey = new TemplateMethod\BeachJourney(); $journey = new TemplateMethod\BeachJourney();
@@ -25,7 +24,7 @@ class JourneyTest extends \PHPUnit_Framework_TestCase
} }
/** /**
* How to test an abstract template method with PHPUnit * How to test an abstract template method with PHPUnit.
*/ */
public function testLasVegas() public function testLasVegas()
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Behavioral\Visitor; namespace DesignPatterns\Behavioral\Visitor;
/** /**
* An example of a Visitor: Group * An example of a Visitor: Group.
*/ */
class Group extends Role class Group extends Role
{ {
@@ -25,6 +25,6 @@ class Group extends Role
*/ */
public function getName() public function getName()
{ {
return "Group: " . $this->name; return 'Group: '.$this->name;
} }
} }

View File

@@ -3,12 +3,12 @@
namespace DesignPatterns\Behavioral\Visitor; namespace DesignPatterns\Behavioral\Visitor;
/** /**
* class Role * class Role.
*/ */
abstract class Role abstract class Role
{ {
/** /**
* This method handles a double dispatch based on the short name of the Visitor * This method handles a double dispatch based on the short name of the Visitor.
* *
* Feel free to override it if your object must call another visiting behavior * Feel free to override it if your object must call another visiting behavior
* *
@@ -21,10 +21,10 @@ abstract class Role
// this trick to simulate double-dispatch based on type-hinting // this trick to simulate double-dispatch based on type-hinting
$klass = get_called_class(); $klass = get_called_class();
preg_match('#([^\\\\]+)$#', $klass, $extract); preg_match('#([^\\\\]+)$#', $klass, $extract);
$visitingMethod = 'visit' . $extract[1]; $visitingMethod = 'visit'.$extract[1];
// this ensures strong typing with visitor interface, not some visitor objects // this ensures strong typing with visitor interface, not some visitor objects
if (!method_exists(__NAMESPACE__ . '\RoleVisitorInterface', $visitingMethod)) { if (!method_exists(__NAMESPACE__.'\RoleVisitorInterface', $visitingMethod)) {
throw new \InvalidArgumentException("The visitor you provide cannot visit a $klass instance"); throw new \InvalidArgumentException("The visitor you provide cannot visit a $klass instance");
} }

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Behavioral\Visitor; namespace DesignPatterns\Behavioral\Visitor;
/** /**
* Visitor Pattern * Visitor Pattern.
* *
* An implementation of a concrete Visitor * An implementation of a concrete Visitor
*/ */
@@ -14,7 +14,7 @@ class RolePrintVisitor implements RoleVisitorInterface
*/ */
public function visitGroup(Group $role) public function visitGroup(Group $role)
{ {
echo "Role: " . $role->getName(); echo 'Role: '.$role->getName();
} }
/** /**
@@ -22,6 +22,6 @@ class RolePrintVisitor implements RoleVisitorInterface
*/ */
public function visitUser(User $role) public function visitUser(User $role)
{ {
echo "Role: " . $role->getName(); echo 'Role: '.$role->getName();
} }
} }

View File

@@ -3,11 +3,11 @@
namespace DesignPatterns\Behavioral\Visitor; namespace DesignPatterns\Behavioral\Visitor;
/** /**
* Visitor Pattern * Visitor Pattern.
* *
* The contract for the visitor. * The contract for the visitor.
* *
* Note 1 : in C++ or java, with method polymorphism based on type-hint, there are many * Note 1 : in C++ or Java, with method polymorphism based on type-hint, there are many
* methods visit() with different type for the 'role' parameter. * methods visit() with different type for the 'role' parameter.
* *
* Note 2 : the visitor must not choose itself which method to * Note 2 : the visitor must not choose itself which method to
@@ -16,14 +16,14 @@ namespace DesignPatterns\Behavioral\Visitor;
interface RoleVisitorInterface interface RoleVisitorInterface
{ {
/** /**
* Visit a User object * Visit a User object.
* *
* @param \DesignPatterns\Behavioral\Visitor\User $role * @param \DesignPatterns\Behavioral\Visitor\User $role
*/ */
public function visitUser(User $role); public function visitUser(User $role);
/** /**
* Visit a Group object * Visit a Group object.
* *
* @param \DesignPatterns\Behavioral\Visitor\Group $role * @param \DesignPatterns\Behavioral\Visitor\Group $role
*/ */

View File

@@ -5,11 +5,10 @@ namespace DesignPatterns\Tests\Visitor\Tests;
use DesignPatterns\Behavioral\Visitor; use DesignPatterns\Behavioral\Visitor;
/** /**
* VisitorTest tests the visitor pattern * VisitorTest tests the visitor pattern.
*/ */
class VisitorTest extends \PHPUnit_Framework_TestCase class VisitorTest extends \PHPUnit_Framework_TestCase
{ {
protected $visitor; protected $visitor;
protected function setUp() protected function setUp()
@@ -20,8 +19,8 @@ class VisitorTest extends \PHPUnit_Framework_TestCase
public function getRole() public function getRole()
{ {
return array( return array(
array(new Visitor\User("Dominik"), 'Role: User Dominik'), array(new Visitor\User('Dominik'), 'Role: User Dominik'),
array(new Visitor\Group("Administrators"), 'Role: Group: Administrators') array(new Visitor\Group('Administrators'), 'Role: Group: Administrators'),
); );
} }

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Behavioral\Visitor; namespace DesignPatterns\Behavioral\Visitor;
/** /**
* Visitor Pattern * Visitor Pattern.
* *
* One example for a visitee. Each visitee has to extends Role * One example for a visitee. Each visitee has to extends Role
*/ */
@@ -27,6 +27,6 @@ class User extends Role
*/ */
public function getName() public function getName()
{ {
return "User " . $this->name; return 'User '.$this->name;
} }
} }

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Creational\AbstractFactory; namespace DesignPatterns\Creational\AbstractFactory;
/** /**
* class AbstractFactory * class AbstractFactory.
* *
* Sometimes also known as "Kit" in a GUI libraries. * Sometimes also known as "Kit" in a GUI libraries.
* *
@@ -20,7 +20,7 @@ namespace DesignPatterns\Creational\AbstractFactory;
abstract class AbstractFactory abstract class AbstractFactory
{ {
/** /**
* Creates a text component * Creates a text component.
* *
* @param string $content * @param string $content
* *
@@ -29,7 +29,7 @@ abstract class AbstractFactory
abstract public function createText($content); abstract public function createText($content);
/** /**
* Creates a picture component * Creates a picture component.
* *
* @param string $path * @param string $path
* @param string $name * @param string $name

View File

@@ -5,14 +5,14 @@ namespace DesignPatterns\Creational\AbstractFactory\Html;
use DesignPatterns\Creational\AbstractFactory\Picture as BasePicture; use DesignPatterns\Creational\AbstractFactory\Picture as BasePicture;
/** /**
* Class Picture * Class Picture.
* *
* Picture is a concrete image for HTML rendering * Picture is a concrete image for HTML rendering
*/ */
class Picture extends BasePicture class Picture extends BasePicture
{ {
/** /**
* some crude rendering from HTML output * some crude rendering from HTML output.
* *
* @return string * @return string
*/ */

View File

@@ -5,19 +5,19 @@ namespace DesignPatterns\Creational\AbstractFactory\Html;
use DesignPatterns\Creational\AbstractFactory\Text as BaseText; use DesignPatterns\Creational\AbstractFactory\Text as BaseText;
/** /**
* Class Text * Class Text.
* *
* Text is a concrete text for HTML rendering * Text is a concrete text for HTML rendering
*/ */
class Text extends BaseText class Text extends BaseText
{ {
/** /**
* some crude rendering from HTML output * some crude rendering from HTML output.
* *
* @return string * @return string
*/ */
public function render() public function render()
{ {
return '<div>' . htmlspecialchars($this->text) . '</div>'; return '<div>'.htmlspecialchars($this->text).'</div>';
} }
} }

View File

@@ -3,14 +3,14 @@
namespace DesignPatterns\Creational\AbstractFactory; namespace DesignPatterns\Creational\AbstractFactory;
/** /**
* Class HtmlFactory * Class HtmlFactory.
* *
* HtmlFactory is a concrete factory for HTML component * HtmlFactory is a concrete factory for HTML component
*/ */
class HtmlFactory extends AbstractFactory class HtmlFactory extends AbstractFactory
{ {
/** /**
* Creates a picture component * Creates a picture component.
* *
* @param string $path * @param string $path
* @param string $name * @param string $name
@@ -23,7 +23,7 @@ class HtmlFactory extends AbstractFactory
} }
/** /**
* Creates a text component * Creates a text component.
* *
* @param string $content * @param string $content
* *

View File

@@ -5,14 +5,14 @@ namespace DesignPatterns\Creational\AbstractFactory\Json;
use DesignPatterns\Creational\AbstractFactory\Picture as BasePicture; use DesignPatterns\Creational\AbstractFactory\Picture as BasePicture;
/** /**
* Class Picture * Class Picture.
* *
* Picture is a concrete image for JSON rendering * Picture is a concrete image for JSON rendering
*/ */
class Picture extends BasePicture class Picture extends BasePicture
{ {
/** /**
* some crude rendering from JSON output * some crude rendering from JSON output.
* *
* @return string * @return string
*/ */

View File

@@ -5,14 +5,14 @@ namespace DesignPatterns\Creational\AbstractFactory\Json;
use DesignPatterns\Creational\AbstractFactory\Text as BaseText; use DesignPatterns\Creational\AbstractFactory\Text as BaseText;
/** /**
* Class Text * Class Text.
* *
* Text is a text component with a JSON rendering * Text is a text component with a JSON rendering
*/ */
class Text extends BaseText class Text extends BaseText
{ {
/** /**
* some crude rendering from JSON output * some crude rendering from JSON output.
* *
* @return string * @return string
*/ */

View File

@@ -3,16 +3,15 @@
namespace DesignPatterns\Creational\AbstractFactory; namespace DesignPatterns\Creational\AbstractFactory;
/** /**
* Class JsonFactory * Class JsonFactory.
* *
* JsonFactory is a factory for creating a family of JSON component * JsonFactory is a factory for creating a family of JSON component
* (example for ajax) * (example for ajax)
*/ */
class JsonFactory extends AbstractFactory class JsonFactory extends AbstractFactory
{ {
/** /**
* Creates a picture component * Creates a picture component.
* *
* @param string $path * @param string $path
* @param string $name * @param string $name
@@ -25,7 +24,7 @@ class JsonFactory extends AbstractFactory
} }
/** /**
* Creates a text component * Creates a text component.
* *
* @param string $content * @param string $content
* *

View File

@@ -3,16 +3,15 @@
namespace DesignPatterns\Creational\AbstractFactory; namespace DesignPatterns\Creational\AbstractFactory;
/** /**
* Interface MediaInterface * Interface MediaInterface.
* *
* This contract is not part of the pattern, in general case, each component * This contract is not part of the pattern, in general case, each component
* are not related * are not related
*/ */
interface MediaInterface interface MediaInterface
{ {
/** /**
* some crude rendering from JSON or html output (depended on concrete class) * some crude rendering from JSON or html output (depended on concrete class).
* *
* @return string * @return string
*/ */

View File

@@ -3,11 +3,10 @@
namespace DesignPatterns\Creational\AbstractFactory; namespace DesignPatterns\Creational\AbstractFactory;
/** /**
* Class Picture * Class Picture.
*/ */
abstract class Picture implements MediaInterface abstract class Picture implements MediaInterface
{ {
/** /**
* @var string * @var string
*/ */

View File

@@ -7,7 +7,7 @@ use DesignPatterns\Creational\AbstractFactory\HtmlFactory;
use DesignPatterns\Creational\AbstractFactory\JsonFactory; use DesignPatterns\Creational\AbstractFactory\JsonFactory;
/** /**
* AbstractFactoryTest tests concrete factories * AbstractFactoryTest tests concrete factories.
*/ */
class AbstractFactoryTest extends \PHPUnit_Framework_TestCase class AbstractFactoryTest extends \PHPUnit_Framework_TestCase
{ {
@@ -15,7 +15,7 @@ class AbstractFactoryTest extends \PHPUnit_Framework_TestCase
{ {
return array( return array(
array(new JsonFactory()), array(new JsonFactory()),
array(new HtmlFactory()) array(new HtmlFactory()),
); );
} }
@@ -31,7 +31,7 @@ class AbstractFactoryTest extends \PHPUnit_Framework_TestCase
$article = array( $article = array(
$factory->createText('Lorem Ipsum'), $factory->createText('Lorem Ipsum'),
$factory->createPicture('/image.jpg', 'caption'), $factory->createPicture('/image.jpg', 'caption'),
$factory->createText('footnotes') $factory->createText('footnotes'),
); );
$this->assertContainsOnly('DesignPatterns\Creational\AbstractFactory\MediaInterface', $article); $this->assertContainsOnly('DesignPatterns\Creational\AbstractFactory\MediaInterface', $article);

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Creational\AbstractFactory; namespace DesignPatterns\Creational\AbstractFactory;
/** /**
* Class Text * Class Text.
*/ */
abstract class Text implements MediaInterface abstract class Text implements MediaInterface
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Creational\Builder; namespace DesignPatterns\Creational\Builder;
/** /**
* BikeBuilder builds bike * BikeBuilder builds bike.
*/ */
class BikeBuilder implements BuilderInterface class BikeBuilder implements BuilderInterface
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Creational\Builder; namespace DesignPatterns\Creational\Builder;
/** /**
* CarBuilder builds car * CarBuilder builds car.
*/ */
class CarBuilder implements BuilderInterface class CarBuilder implements BuilderInterface
{ {

View File

@@ -10,9 +10,8 @@ namespace DesignPatterns\Creational\Builder;
*/ */
class Director class Director
{ {
/** /**
* The director don't know 'bout concrete part * The director don't know about concrete part.
* *
* @param BuilderInterface $builder * @param BuilderInterface $builder
* *

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Creational\Builder\Parts; namespace DesignPatterns\Creational\Builder\Parts;
/** /**
* Bike is a bike * Bike is a bike.
*/ */
class Bike extends Vehicle class Bike extends Vehicle
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Creational\Builder\Parts; namespace DesignPatterns\Creational\Builder\Parts;
/** /**
* Car is a car * Car is a car.
*/ */
class Car extends Vehicle class Car extends Vehicle
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Creational\Builder\Parts; namespace DesignPatterns\Creational\Builder\Parts;
/** /**
* Class Door * Class Door.
*/ */
class Door class Door
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Creational\Builder\Parts; namespace DesignPatterns\Creational\Builder\Parts;
/** /**
* Class Engine * Class Engine.
*/ */
class Engine class Engine
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Creational\Builder\Parts; namespace DesignPatterns\Creational\Builder\Parts;
/** /**
* VehicleInterface is a contract for a vehicle * Vehicle class is an abstraction for a vehicle.
*/ */
abstract class Vehicle abstract class Vehicle
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Creational\Builder\Parts; namespace DesignPatterns\Creational\Builder\Parts;
/** /**
* Class Wheel * Class Wheel.
*/ */
class Wheel class Wheel
{ {

View File

@@ -2,17 +2,16 @@
namespace DesignPatterns\Creational\Builder\Tests; namespace DesignPatterns\Creational\Builder\Tests;
use DesignPatterns\Creational\Builder\Director;
use DesignPatterns\Creational\Builder\CarBuilder;
use DesignPatterns\Creational\Builder\BikeBuilder; use DesignPatterns\Creational\Builder\BikeBuilder;
use DesignPatterns\Creational\Builder\BuilderInterface; use DesignPatterns\Creational\Builder\BuilderInterface;
use DesignPatterns\Creational\Builder\CarBuilder;
use DesignPatterns\Creational\Builder\Director;
/** /**
* DirectorTest tests the builder pattern * DirectorTest tests the builder pattern.
*/ */
class DirectorTest extends \PHPUnit_Framework_TestCase class DirectorTest extends \PHPUnit_Framework_TestCase
{ {
protected $director; protected $director;
protected function setUp() protected function setUp()
@@ -24,7 +23,7 @@ class DirectorTest extends \PHPUnit_Framework_TestCase
{ {
return array( return array(
array(new CarBuilder()), array(new CarBuilder()),
array(new BikeBuilder()) array(new BikeBuilder()),
); );
} }

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Creational\FactoryMethod; namespace DesignPatterns\Creational\FactoryMethod;
/** /**
* Bicycle is a bicycle * Bicycle is a bicycle.
*/ */
class Bicycle implements VehicleInterface class Bicycle implements VehicleInterface
{ {
@@ -13,7 +13,7 @@ class Bicycle implements VehicleInterface
protected $color; protected $color;
/** /**
* sets the color of the bicycle * sets the color of the bicycle.
* *
* @param string $rgb * @param string $rgb
*/ */

View File

@@ -3,16 +3,15 @@
namespace DesignPatterns\Creational\FactoryMethod; namespace DesignPatterns\Creational\FactoryMethod;
/** /**
* class FactoryMethod * class FactoryMethod.
*/ */
abstract class FactoryMethod abstract class FactoryMethod
{ {
const CHEAP = 1; const CHEAP = 1;
const FAST = 2; const FAST = 2;
/** /**
* The children of the class must implement this method * The children of the class must implement this method.
* *
* Sometimes this method can be public to get "raw" object * Sometimes this method can be public to get "raw" object
* *
@@ -23,7 +22,7 @@ abstract class FactoryMethod
abstract protected function createVehicle($type); abstract protected function createVehicle($type);
/** /**
* Creates a new vehicle * Creates a new vehicle.
* *
* @param int $type * @param int $type
* *
@@ -32,7 +31,7 @@ abstract class FactoryMethod
public function create($type) public function create($type)
{ {
$obj = $this->createVehicle($type); $obj = $this->createVehicle($type);
$obj->setColor("#f00"); $obj->setColor('#f00');
return $obj; return $obj;
} }

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Creational\FactoryMethod; namespace DesignPatterns\Creational\FactoryMethod;
/** /**
* Ferrari is a italian car * Ferrari is a italian car.
*/ */
class Ferrari implements VehicleInterface class Ferrari implements VehicleInterface
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Creational\FactoryMethod; namespace DesignPatterns\Creational\FactoryMethod;
/** /**
* GermanFactory is a vehicle factory in Germany * GermanFactory is a vehicle factory in Germany.
*/ */
class GermanFactory extends FactoryMethod class GermanFactory extends FactoryMethod
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Creational\FactoryMethod; namespace DesignPatterns\Creational\FactoryMethod;
/** /**
* ItalianFactory is vehicle factory in Italy * ItalianFactory is vehicle factory in Italy.
*/ */
class ItalianFactory extends FactoryMethod class ItalianFactory extends FactoryMethod
{ {

View File

@@ -3,7 +3,7 @@
namespace DesignPatterns\Creational\FactoryMethod; namespace DesignPatterns\Creational\FactoryMethod;
/** /**
* Porsche is a german car * Porsche is a german car.
*/ */
class Porsche implements VehicleInterface class Porsche implements VehicleInterface
{ {

View File

@@ -7,21 +7,20 @@ use DesignPatterns\Creational\FactoryMethod\GermanFactory;
use DesignPatterns\Creational\FactoryMethod\ItalianFactory; use DesignPatterns\Creational\FactoryMethod\ItalianFactory;
/** /**
* FactoryMethodTest tests the factory method pattern * FactoryMethodTest tests the factory method pattern.
*/ */
class FactoryMethodTest extends \PHPUnit_Framework_TestCase class FactoryMethodTest extends \PHPUnit_Framework_TestCase
{ {
protected $type = array( protected $type = array(
FactoryMethod::CHEAP, FactoryMethod::CHEAP,
FactoryMethod::FAST FactoryMethod::FAST,
); );
public function getShop() public function getShop()
{ {
return array( return array(
array(new GermanFactory()), array(new GermanFactory()),
array(new ItalianFactory()) array(new ItalianFactory()),
); );
} }

View File

@@ -3,12 +3,12 @@
namespace DesignPatterns\Creational\FactoryMethod; namespace DesignPatterns\Creational\FactoryMethod;
/** /**
* VehicleInterface is a contract for a vehicle * VehicleInterface is a contract for a vehicle.
*/ */
interface VehicleInterface interface VehicleInterface
{ {
/** /**
* sets the color of the vehicle * sets the color of the vehicle.
* *
* @param string $rgb * @param string $rgb
*/ */

View File

@@ -3,24 +3,22 @@
namespace DesignPatterns\Creational\Multiton; namespace DesignPatterns\Creational\Multiton;
/** /**
* class Multiton * class Multiton.
*/ */
class Multiton class Multiton
{ {
/** /**
* * the first instance.
* the first instance
*/ */
const INSTANCE_1 = '1'; const INSTANCE_1 = '1';
/** /**
* * the second instance.
* the second instance
*/ */
const INSTANCE_2 = '2'; const INSTANCE_2 = '2';
/** /**
* holds the named instances * holds the named instances.
* *
* @var array * @var array
*/ */
@@ -28,7 +26,6 @@ class Multiton
/** /**
* should not be called from outside: private! * should not be called from outside: private!
*
*/ */
private function __construct() private function __construct()
{ {
@@ -36,7 +33,7 @@ class Multiton
/** /**
* gets the instance with the given name, e.g. Multiton::INSTANCE_1 * gets the instance with the given name, e.g. Multiton::INSTANCE_1
* uses lazy initialization * uses lazy initialization.
* *
* @param string $instanceName * @param string $instanceName
* *
@@ -52,7 +49,7 @@ class Multiton
} }
/** /**
* prevent instance from being cloned * prevent instance from being cloned.
* *
* @return void * @return void
*/ */
@@ -61,7 +58,7 @@ class Multiton
} }
/** /**
* prevent instance from being unserialized * prevent instance from being unserialized.
* *
* @return void * @return void
*/ */

View File

@@ -4,7 +4,6 @@ namespace DesignPatterns\Creational\Pool;
class Pool class Pool
{ {
private $instances = array(); private $instances = array();
private $class; private $class;

View File

@@ -4,11 +4,10 @@ namespace DesignPatterns\Creational\Pool;
class Processor class Processor
{ {
private $pool; private $pool;
private $processing = 0; private $processing = 0;
private $maxProcesses = 3; private $maxProcesses = 3;
private $waitingQueue = []; private $waitingQueue = array();
public function __construct(Pool $pool) public function __construct(Pool $pool)
{ {

Some files were not shown because too many files have changed in this diff Show More