Merge commit 'refs/pull/origin/86'

This commit is contained in:
Dominik Liebler
2014-06-06 09:17:33 +02:00
217 changed files with 1136 additions and 673 deletions

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\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

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\ChainOfResponsibilities; namespace DesignPatterns\Behavioral\ChainOfResponsibilities;
/** /**
* Request is a request which goes through the chain of responsibilities. * Request is a request which goes through the chain of responsibilities.

View File

@@ -1,9 +1,9 @@
<?php <?php
namespace DesignPatterns\ChainOfResponsibilities\Responsible; namespace DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible;
use DesignPatterns\ChainOfResponsibilities\Handler; use DesignPatterns\Behavioral\ChainOfResponsibilities\Handler;
use DesignPatterns\ChainOfResponsibilities\Request; use DesignPatterns\Behavioral\ChainOfResponsibilities\Request;
/** /**
* Class FastStorage * Class FastStorage

View File

@@ -1,9 +1,9 @@
<?php <?php
namespace DesignPatterns\ChainOfResponsibilities\Responsible; namespace DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible;
use DesignPatterns\ChainOfResponsibilities\Handler; use DesignPatterns\Behavioral\ChainOfResponsibilities\Handler;
use DesignPatterns\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

View File

@@ -1,9 +1,11 @@
<?php <?php
namespace DesignPatterns\Tests\ChainOfResponsibilities; namespace DesignPatterns\Behavioral\ChainOfResponsibilities\Tests;
use DesignPatterns\ChainOfResponsibilities\Request; use DesignPatterns\Behavioral\ChainOfResponsibilities\Request;
use DesignPatterns\ChainOfResponsibilities\Responsible; use DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible\FastStorage;
use DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible\SlowStorage;
use DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible;
/** /**
* ChainTest tests the CoR * ChainTest tests the CoR
@@ -11,12 +13,15 @@ use DesignPatterns\ChainOfResponsibilities\Responsible;
class ChainTest extends \PHPUnit_Framework_TestCase class ChainTest extends \PHPUnit_Framework_TestCase
{ {
/**
* @var FastStorage
*/
protected $chain; protected $chain;
protected function setUp() protected function setUp()
{ {
$this->chain = new Responsible\FastStorage(array('bar' => 'baz')); $this->chain = new FastStorage(array('bar' => 'baz'));
$this->chain->append(new Responsible\SlowStorage(array('bar' => 'baz', 'foo' => 'bar'))); $this->chain->append(new SlowStorage(array('bar' => 'baz', 'foo' => 'bar')));
} }
public function makeRequest() public function makeRequest()
@@ -40,7 +45,8 @@ class ChainTest extends \PHPUnit_Framework_TestCase
$this->assertObjectHasAttribute('response', $request); $this->assertObjectHasAttribute('response', $request);
$this->assertEquals('baz', $request->response); $this->assertEquals('baz', $request->response);
// despite both handle owns the 'bar' key, the FastStorage is responding first // despite both handle owns the 'bar' key, the FastStorage is responding first
$this->assertEquals('DesignPatterns\ChainOfResponsibilities\Responsible\FastStorage', $request->forDebugOnly); $className = 'DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible\FastStorage';
$this->assertEquals($className, $request->forDebugOnly);
} }
/** /**
@@ -55,7 +61,8 @@ class ChainTest extends \PHPUnit_Framework_TestCase
$this->assertObjectHasAttribute('response', $request); $this->assertObjectHasAttribute('response', $request);
$this->assertEquals('bar', $request->response); $this->assertEquals('bar', $request->response);
// FastStorage has no 'foo' key, the SlowStorage is responding // FastStorage has no 'foo' key, the SlowStorage is responding
$this->assertEquals('DesignPatterns\ChainOfResponsibilities\Responsible\SlowStorage', $request->forDebugOnly); $className = 'DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible\SlowStorage';
$this->assertEquals($className, $request->forDebugOnly);
} }
/** /**
@@ -68,6 +75,7 @@ class ChainTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($ret); $this->assertFalse($ret);
// the last responsible : // the last responsible :
$this->assertEquals('DesignPatterns\ChainOfResponsibilities\Responsible\SlowStorage', $request->forDebugOnly); $className = 'DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible\SlowStorage';
$this->assertEquals($className, $request->forDebugOnly);
} }
} }

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Command; namespace DesignPatterns\Behavioral\Command;
/** /**
* class CommandInterface * class CommandInterface

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Command; 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

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Command; namespace DesignPatterns\Behavioral\Command;
/** /**
* Invoker is using the command given to it. * Invoker is using the command given to it.

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\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

View File

@@ -1,10 +1,10 @@
<?php <?php
namespace DesignPatterns\Tests\Command; namespace DesignPatterns\Behavioral\Command\Tests;
use DesignPatterns\Command\Invoker; use DesignPatterns\Behavioral\Command\Invoker;
use DesignPatterns\Command\Receiver; use DesignPatterns\Behavioral\Command\Receiver;
use DesignPatterns\Command\HelloCommand; 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
@@ -12,12 +12,18 @@ use DesignPatterns\Command\HelloCommand;
class CommandTest extends \PHPUnit_Framework_TestCase class CommandTest extends \PHPUnit_Framework_TestCase
{ {
/**
* @var Invoker
*/
protected $invoker; protected $invoker;
/**
* @var Receiver
*/
protected $receiver; protected $receiver;
protected function setUp() protected function setUp()
{ {
// this is the context of the application
$this->invoker = new Invoker(); $this->invoker = new Invoker();
$this->receiver = new Receiver(); $this->receiver = new Receiver();
} }

View File

@@ -0,0 +1,32 @@
<?php
namespace DesignPatterns\Behavioral\Iterator;
class Book
{
private $author;
private $title;
public function __construct($title, $author)
{
$this->author = $author;
$this->title = $title;
}
public function getAuthor()
{
return $this->author;
}
public function getTitle()
{
return $this->title;
}
public function getAuthorAndTitle()
{
return $this->getTitle() . ' by ' . $this->getAuthor();
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace DesignPatterns\Behavioral\Iterator;
class BookList implements \Countable
{
private $books;
public function getBook($bookNumberToGet)
{
if ((int)$bookNumberToGet <= $this->count()) {
return $this->books[$bookNumberToGet];
}
return null;
}
public function addBook(Book $book)
{
$this->books[] = $book;
return $this->count();
}
public function removeBook(Book $bookToRemove)
{
foreach ($this as $key => $book) {
/** @var Book $book */
if ($book->getAuthorAndTitle() === $bookToRemove->getAuthorAndTitle()) {
unset($this->books[$key]);
}
}
return $this->count();
}
public function count()
{
return count($this->books);
}
}

View File

@@ -0,0 +1,77 @@
<?php
namespace DesignPatterns\Behavioral\Iterator;
class BookListIterator implements \Iterator
{
/**
* @var BookList
*/
protected $bookList;
/**
* @var int
*/
protected $currentBook = 0;
public function __construct(BookList $bookList)
{
$this->bookList = $bookList;
}
/**
* 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()
{
$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 boolean The return value will be casted to boolean and then evaluated.
* Returns true on success or false on failure.
*/
public function valid()
{
return $this->currentBook < $this->bookList->count();
}
/**
* (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 = 0;
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace DesignPatterns\Behavioral\Iterator;
class BookListReverseIterator extends BookListIterator
{
public function __construct(BookList $bookList)
{
$this->bookList = $bookList;
$this->currentBook = $this->bookList->count() - 1;
}
public function next()
{
$this->currentBook--;
}
public function valid()
{
return 0 <= $this->currentBook;
}
}

View File

@@ -0,0 +1,66 @@
<?php
namespace DesignPatterns\Behavioral\Iterator\Tests;
use DesignPatterns\Behavioral\Iterator\Book;
use DesignPatterns\Behavioral\Iterator\BookList;
use DesignPatterns\Behavioral\Iterator\BookListIterator;
use DesignPatterns\Behavioral\Iterator\BookListReverseIterator;
class IteratorTest extends \PHPUnit_Framework_TestCase
{
/**
* @var BookList
*/
protected $bookList;
protected function setUp()
{
$this->bookList = new BookList();
$this->bookList->addBook(new Book('Learning PHP Design Patterns', 'William Sanders'));
$this->bookList->addBook(new Book('Professional Php Design Patterns', 'Aaron Saray'));
$this->bookList->addBook(new Book('Clean Code', 'Robert C. Martin'));
}
public function expectedAuthors()
{
return array(
array(
array(
'Learning PHP Design Patterns by William Sanders',
'Professional Php Design Patterns by Aaron Saray',
'Clean Code by Robert C. Martin'
)
),
);
}
/**
* @dataProvider expectedAuthors
*/
public function testUseAIteratorAndValidateAuthors($expected)
{
$iterator = new BookListIterator($this->bookList);
while ($iterator->valid()) {
$expectedBook = array_shift($expected);
$this->assertEquals($expectedBook, $iterator->current()->getAuthorAndTitle());
$iterator->next();
}
}
/**
* @dataProvider expectedAuthors
*/
public function testUseAReverseIteratorAndValidateAuthors($expected)
{
$iterator = new BookListReverseIterator($this->bookList);
while ($iterator->valid()) {
$expectedBook = array_pop($expected);
$this->assertEquals($expectedBook, $iterator->current()->getAuthorAndTitle());
$iterator->next();
}
}
}

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Mediator; namespace DesignPatterns\Behavioral\Mediator;
/** /**
* Colleague is an abstract colleague who works together but he only knows * Colleague is an abstract colleague who works together but he only knows

View File

@@ -1,20 +1,29 @@
<?php <?php
namespace DesignPatterns\Mediator; namespace DesignPatterns\Behavioral\Mediator;
use DesignPatterns\Mediator\Subsystem; 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
{ {
// you could have an array /**
* @var Subsystem\Server
*/
protected $server; protected $server;
/**
* @var Subsystem\Database
*/
protected $database; protected $database;
/**
* @var Subsystem\Client
*/
protected $client; protected $client;
/** /**
@@ -39,7 +48,6 @@ class Mediator implements MediatorInterface
/** /**
* query db * query db
*
* @return mixed * @return mixed
*/ */
public function queryDb() public function queryDb()

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Mediator; namespace DesignPatterns\Behavioral\Mediator;
/** /**
* MediatorInterface is a contract for the Mediator * MediatorInterface is a contract for the Mediator

View File

@@ -1,8 +1,8 @@
<?php <?php
namespace DesignPatterns\Mediator\Subsystem; namespace DesignPatterns\Behavioral\Mediator\Subsystem;
use DesignPatterns\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

View File

@@ -1,8 +1,8 @@
<?php <?php
namespace DesignPatterns\Mediator\Subsystem; namespace DesignPatterns\Behavioral\Mediator\Subsystem;
use DesignPatterns\Mediator\Colleague; use DesignPatterns\Behavioral\Mediator\Colleague;
/** /**
* Database is a database service * Database is a database service

View File

@@ -1,8 +1,8 @@
<?php <?php
namespace DesignPatterns\Mediator\Subsystem; namespace DesignPatterns\Behavioral\Mediator\Subsystem;
use DesignPatterns\Mediator\Colleague; use DesignPatterns\Behavioral\Mediator\Colleague;
/** /**
* Server serves responses * Server serves responses

View File

@@ -1,11 +1,11 @@
<?php <?php
namespace DesignPatterns\Tests\Mediator; namespace DesignPatterns\Tests\Mediator\Tests;
use DesignPatterns\Mediator\Mediator; use DesignPatterns\Behavioral\Mediator\Mediator;
use DesignPatterns\Mediator\Subsystem\Database; use DesignPatterns\Behavioral\Mediator\Subsystem\Database;
use DesignPatterns\Mediator\Subsystem\Client; use DesignPatterns\Behavioral\Mediator\Subsystem\Client;
use DesignPatterns\Mediator\Subsystem\Server; use DesignPatterns\Behavioral\Mediator\Subsystem\Server;
/** /**
* MediatorTest tests hello world * MediatorTest tests hello world

View 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
}
}

View 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;
}
}

View 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();
}
}

View 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

View File

@@ -0,0 +1,69 @@
<?php
namespace DesignPatterns\Behavioral\Memento\Tests;
use DesignPatterns\Behavioral\Memento\Originator;
/**
* 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);
}
}

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\NullObject; namespace DesignPatterns\Behavioral\NullObject;
/** /**
* LoggerInterface is a contract for logging something * LoggerInterface is a contract for logging something

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\NullObject; namespace DesignPatterns\Behavioral\NullObject;
/** /**
* Performance concerns : ok there is a call for nothing but we spare an "if is_null" * Performance concerns : ok there is a call for nothing but we spare an "if is_null"

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\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

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\NullObject; namespace DesignPatterns\Behavioral\NullObject;
/** /**
* Service is dummy service that uses a logger * Service is dummy service that uses a logger

View File

@@ -1,10 +1,10 @@
<?php <?php
namespace DesignPatterns\Tests\NullObject; namespace DesignPatterns\Behavioral\NullObject\Tests;
use DesignPatterns\NullObject\NullLogger; use DesignPatterns\Behavioral\NullObject\NullLogger;
use DesignPatterns\NullObject\Service; use DesignPatterns\Behavioral\NullObject\Service;
use DesignPatterns\NullObject\PrintLogger; use DesignPatterns\Behavioral\NullObject\PrintLogger;
/** /**
* LoggerTest tests for different loggers * LoggerTest tests for different loggers
@@ -24,7 +24,7 @@ class LoggerTest extends \PHPUnit_Framework_TestCase
public function testStandardLogger() public function testStandardLogger()
{ {
$service = new Service(new PrintLogger()); $service = new Service(new PrintLogger());
$this->expectOutputString('We are in DesignPatterns\NullObject\Service::doSomething'); $this->expectOutputString('We are in DesignPatterns\Behavioral\NullObject\Service::doSomething');
$service->doSomething(); $service->doSomething();
} }
} }

View File

@@ -1,9 +1,9 @@
<?php <?php
namespace DesignPatterns\Tests\Observer; namespace DesignPatterns\Behavioral\Observer\Tests;
use DesignPatterns\Observer\UserObserver; use DesignPatterns\Behavioral\Observer\UserObserver;
use DesignPatterns\Observer\User; use DesignPatterns\Behavioral\Observer\User;
/** /**
* ObserverTest tests the Observer pattern * ObserverTest tests the Observer pattern
@@ -23,7 +23,7 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
*/ */
public function testNotify() public function testNotify()
{ {
$this->expectOutputString('DesignPatterns\Observer\User has been updated'); $this->expectOutputString('DesignPatterns\Behavioral\Observer\User has been updated');
$subject = new User(); $subject = new User();
$subject->attach($this->observer); $subject->attach($this->observer);
@@ -53,10 +53,9 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
$subject->attach($observer); $subject->attach($observer);
$observer->expects($this->once()) $observer->expects($this->once())
->method('update') ->method('update')
->with($subject); ->with($subject);
$subject->notify(); $subject->notify();
} }
}
}

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Observer; namespace DesignPatterns\Behavioral\Observer;
/** /**
* Observer pattern : The observed object (the subject) * Observer pattern : The observed object (the subject)

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Observer; namespace DesignPatterns\Behavioral\Observer;
/** /**
* class UserObserver * class UserObserver

18
Behavioral/README.md Normal file
View File

@@ -0,0 +1,18 @@
# Behavioral
In software engineering, behavioral design patterns are design patterns that
identify common communication patterns between objects and realize these
patterns. By doing so, these patterns increase flexibility in carrying out this
communication.
* [ChainOfResponsibilities](ChainOfResponsibilities) [:notebook:](http://en.wikipedia.org/wiki/Chain_of_responsibility_pattern)
* [Command](Command) [:notebook:](http://en.wikipedia.org/wiki/Command_pattern)
* [Iterator](Iterator) [:notebook:](http://en.wikipedia.org/wiki/Iterator_pattern)
* [Mediator](Mediator) [:notebook:](http://en.wikipedia.org/wiki/Mediator_pattern)
* [NullObject](NullObject) [:notebook:](http://en.wikipedia.org/wiki/Null_Object_pattern)
* [Observer](Observer) [:notebook:](http://en.wikipedia.org/wiki/Observer_pattern)
* [Specification](Specification) [:notebook:](http://en.wikipedia.org/wiki/Specification_pattern)
* [State](State) [:notebook:](http://en.wikipedia.org/wiki/State_pattern)
* [Strategy](Strategy) [:notebook:](http://en.wikipedia.org/wiki/Strategy_pattern)
* [TemplateMethod](TemplateMethod) [:notebook:](http://en.wikipedia.org/wiki/Template_method_pattern)
* [Visitor](Visitor) [:notebook:](http://en.wikipedia.org/wiki/Visitor_pattern)

View File

@@ -1,5 +1,5 @@
<?php <?php
namespace DesignPatterns\Specification; namespace DesignPatterns\Behavioral\Specification;
/** /**
* An abstract specification allows the creation of wrapped specifications * An abstract specification allows the creation of wrapped specifications
@@ -8,18 +8,18 @@ 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
* *
* @return bool * @return bool
*/ */
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
* *
* @return SpecificationInterface * @return SpecificationInterface
*/ */
public function plus(SpecificationInterface $spec) public function plus(SpecificationInterface $spec)
@@ -29,9 +29,9 @@ 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
* *
* @return SpecificationInterface * @return SpecificationInterface
*/ */
public function either(SpecificationInterface $spec) public function either(SpecificationInterface $spec)
@@ -41,11 +41,11 @@ abstract class AbstractSpecification implements SpecificationInterface
/** /**
* Creates a new logical NOT specification * Creates a new logical NOT specification
* *
* @return SpecificationInterface * @return SpecificationInterface
*/ */
public function not() public function not()
{ {
return new Not($this); return new Not($this);
} }
} }

View File

@@ -1,5 +1,5 @@
<?php <?php
namespace DesignPatterns\Specification; namespace DesignPatterns\Behavioral\Specification;
/** /**
* A logical OR specification * A logical OR specification

View File

@@ -1,5 +1,5 @@
<?php <?php
namespace DesignPatterns\Specification; namespace DesignPatterns\Behavioral\Specification;
/** /**
* An trivial item * An trivial item

View File

@@ -1,5 +1,5 @@
<?php <?php
namespace DesignPatterns\Specification; namespace DesignPatterns\Behavioral\Specification;
/** /**
* A logical Not specification * A logical Not specification
@@ -31,4 +31,4 @@ class Not extends AbstractSpecification
{ {
return !$this->spec->isSatisfiedBy($item); return !$this->spec->isSatisfiedBy($item);
} }
} }

View File

@@ -1,5 +1,5 @@
<?php <?php
namespace DesignPatterns\Specification; namespace DesignPatterns\Behavioral\Specification;
/** /**
* A logical AND specification * A logical AND specification
@@ -12,10 +12,9 @@ class Plus extends AbstractSpecification
/** /**
* Creation of a locical AND of two specifications * Creation of a locical AND of two specifications
* *
* @param SpecificationInterface $left * @param SpecificationInterface $left
* @param SpecificationInterface $right * @param SpecificationInterface $right
*/ */
public function __construct(SpecificationInterface $left, SpecificationInterface $right) public function __construct(SpecificationInterface $left, SpecificationInterface $right)
{ {
@@ -25,13 +24,13 @@ 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
* *
* @return bool * @return bool
*/ */
public function isSatisfiedBy(Item $item) public function isSatisfiedBy(Item $item)
{ {
return $this->left->isSatisfiedBy($item) && $this->right->isSatisfiedBy($item); return $this->left->isSatisfiedBy($item) && $this->right->isSatisfiedBy($item);
} }
} }

View File

@@ -1,5 +1,5 @@
<?php <?php
namespace DesignPatterns\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
@@ -31,17 +31,17 @@ class PriceSpecification extends AbstractSpecification
/** /**
* Checks if Item price falls between bounds * Checks if Item price falls between bounds
* *
* @param Item $item * @param Item $item
* *
* @return bool * @return bool
*/ */
public function isSatisfiedBy(Item $item) public function isSatisfiedBy(Item $item)
{ {
if ( !empty($this->maxPrice) && $item->getPrice() > $this->maxPrice) { if (!empty($this->maxPrice) && $item->getPrice() > $this->maxPrice) {
return false; return false;
} }
if ( !empty($this->minPrice) && $item->getPrice() < $this->minPrice) { if (!empty($this->minPrice) && $item->getPrice() < $this->minPrice) {
return false; return false;
} }

View File

@@ -1,5 +1,5 @@
<?php <?php
namespace DesignPatterns\Specification; namespace DesignPatterns\Behavioral\Specification;
/** /**
* An interface for a specification * An interface for a specification
@@ -8,26 +8,24 @@ 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
* *
* @return bool * @return bool
*/ */
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);
@@ -35,4 +33,4 @@ interface SpecificationInterface
* Creates a logical not specification * Creates a logical not specification
*/ */
public function not(); public function not();
} }

View File

@@ -1,9 +1,9 @@
<?php <?php
namespace DesignPatterns\Tests\Specification; namespace DesignPatterns\Behavioral\Specification\Tests;
use DesignPatterns\Specification\PriceSpecification; use DesignPatterns\Behavioral\Specification\PriceSpecification;
use DesignPatterns\Specification\Item; use DesignPatterns\Behavioral\Specification\Item;
/** /**
* SpecificationTest tests the specification pattern * SpecificationTest tests the specification pattern

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Status; namespace DesignPatterns\Behavioral\State;
/** /**
* Class CreateOrder * Class CreateOrder

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Status; namespace DesignPatterns\Behavioral\State;
/** /**
* Class OrderController * Class OrderController

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Status; namespace DesignPatterns\Behavioral\State;
/** /**
* Class OrderFactory * Class OrderFactory
@@ -9,7 +9,7 @@ class OrderFactory
{ {
private function __construct() private function __construct()
{ {
throw Exception('Can not instance the OrderFactory class!'); throw new \Exception('Can not instance the OrderFactory class!');
} }
/** /**

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Status; namespace DesignPatterns\Behavioral\State;
/** /**
* Class OrderInterface * Class OrderInterface

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Status; namespace DesignPatterns\Behavioral\State;
/** /**
* Class ShippingOrder * Class ShippingOrder

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Strategy; namespace DesignPatterns\Behavioral\Strategy;
/** /**
* Class ComparatorInterface * Class ComparatorInterface

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Strategy; namespace DesignPatterns\Behavioral\Strategy;
/** /**
* Class DateComparator * Class DateComparator

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Strategy; namespace DesignPatterns\Behavioral\Strategy;
/** /**
* Class IdComparator * Class IdComparator

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Strategy; namespace DesignPatterns\Behavioral\Strategy;
/** /**
* Class ObjectCollection * Class ObjectCollection
@@ -30,10 +30,10 @@ 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');
uasort($this->elements, $callback); uasort($this->elements, $callback);

View File

@@ -1,11 +1,11 @@
<?php <?php
namespace DesignPatterns\Tests\Strategy; namespace DesignPatterns\Behavioral\Strategy\Tests;
use DesignPatterns\Strategy\DateComparator; use DesignPatterns\Behavioral\Strategy\DateComparator;
use DesignPatterns\Strategy\IdComparator; use DesignPatterns\Behavioral\Strategy\IdComparator;
use DesignPatterns\Strategy\ObjectCollection; use DesignPatterns\Behavioral\Strategy\ObjectCollection;
use DesignPatterns\Strategy\Strategy; use DesignPatterns\Behavioral\Strategy\Strategy;
/** /**
* Tests for Static Factory pattern * Tests for Static Factory pattern

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\TemplateMethod; namespace DesignPatterns\Behavioral\TemplateMethod;
/** /**
* BeachJourney is vacation at the beach * BeachJourney is vacation at the beach

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\TemplateMethod; namespace DesignPatterns\Behavioral\TemplateMethod;
/** /**
* CityJourney is a journey in a city * CityJourney is a journey in a city

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\TemplateMethod; namespace DesignPatterns\Behavioral\TemplateMethod;
/** /**
* *

View File

@@ -1,8 +1,8 @@
<?php <?php
namespace DesignPatterns\Tests\TemplateMethod; namespace DesignPatterns\Behavioral\TemplateMethod\Tests;
use DesignPatterns\TemplateMethod; use DesignPatterns\Behavioral\TemplateMethod;
/** /**
* JourneyTest tests all journeys * JourneyTest tests all journeys
@@ -29,10 +29,10 @@ class JourneyTest extends \PHPUnit_Framework_TestCase
*/ */
public function testLasVegas() public function testLasVegas()
{ {
$journey = $this->getMockForAbstractClass('DesignPatterns\TemplateMethod\Journey'); $journey = $this->getMockForAbstractClass('DesignPatterns\Behavioral\TemplateMethod\Journey');
$journey->expects($this->once()) $journey->expects($this->once())
->method('enjoyVacation') ->method('enjoyVacation')
->will($this->returnCallback(array($this, 'mockUpVacation'))); ->will($this->returnCallback(array($this, 'mockUpVacation')));
$this->expectOutputRegex('#Las Vegas#'); $this->expectOutputRegex('#Las Vegas#');
$journey->takeATrip(); $journey->takeATrip();
} }
@@ -41,5 +41,4 @@ class JourneyTest extends \PHPUnit_Framework_TestCase
{ {
echo "Fear and loathing in Las Vegas\n"; echo "Fear and loathing in Las Vegas\n";
} }
}
}

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Visitor; namespace DesignPatterns\Behavioral\Visitor;
/** /**
* An example of a Visitor: Group * An example of a Visitor: Group

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Visitor; namespace DesignPatterns\Behavioral\Visitor;
/** /**
* class Role * class Role
@@ -12,7 +12,7 @@ abstract class Role
* *
* 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
* *
* @param \DesignPatterns\Visitor\RoleVisitorInterface $visitor * @param \DesignPatterns\Behavioral\Visitor\RoleVisitorInterface $visitor
* *
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Visitor; namespace DesignPatterns\Behavioral\Visitor;
/** /**
* Visitor Pattern * Visitor Pattern

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Visitor; namespace DesignPatterns\Behavioral\Visitor;
/** /**
* Visitor Pattern * Visitor Pattern
@@ -18,14 +18,14 @@ interface RoleVisitorInterface
/** /**
* Visit a User object * Visit a User object
* *
* @param \DesignPatterns\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\Visitor\Group $role * @param \DesignPatterns\Behavioral\Visitor\Group $role
*/ */
public function visitGroup(Group $role); public function visitGroup(Group $role);
} }

View File

@@ -1,8 +1,8 @@
<?php <?php
namespace DesignPatterns\Tests\Visitor; namespace DesignPatterns\Tests\Visitor\Tests;
use DesignPatterns\Visitor; use DesignPatterns\Behavioral\Visitor;
/** /**
* VisitorTest tests the visitor pattern * VisitorTest tests the visitor pattern
@@ -40,8 +40,7 @@ class VisitorTest extends \PHPUnit_Framework_TestCase
*/ */
public function testUnknownObject() public function testUnknownObject()
{ {
$mock = $this->getMockForAbstractClass('DesignPatterns\Visitor\Role'); $mock = $this->getMockForAbstractClass('DesignPatterns\Behavioral\Visitor\Role');
$mock->accept($this->visitor); $mock->accept($this->visitor);
} }
}
}

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Visitor; namespace DesignPatterns\Behavioral\Visitor;
/** /**
* Visitor Pattern * Visitor Pattern

View File

@@ -1,11 +0,0 @@
<?php
namespace DesignPatterns\Builder\Parts;
/**
* Class Door
*/
class Door
{
}

View File

@@ -1,11 +0,0 @@
<?php
namespace DesignPatterns\Builder\Parts;
/**
* Class Engine
*/
class Engine
{
}

View File

@@ -1,11 +0,0 @@
<?php
namespace DesignPatterns\Builder\Parts;
/**
* Class Wheel
*/
class Wheel
{
}

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\AbstractFactory; namespace DesignPatterns\Creational\AbstractFactory;
/** /**
* class AbstractFactory * class AbstractFactory

View File

@@ -1,8 +1,8 @@
<?php <?php
namespace DesignPatterns\AbstractFactory\Html; namespace DesignPatterns\Creational\AbstractFactory\Html;
use DesignPatterns\AbstractFactory\Picture as BasePicture; use DesignPatterns\Creational\AbstractFactory\Picture as BasePicture;
/** /**
* Class Picture * Class Picture

View File

@@ -1,8 +1,8 @@
<?php <?php
namespace DesignPatterns\AbstractFactory\Html; namespace DesignPatterns\Creational\AbstractFactory\Html;
use DesignPatterns\AbstractFactory\Text as BaseText; use DesignPatterns\Creational\AbstractFactory\Text as BaseText;
/** /**
* Class Text * Class Text

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\AbstractFactory; namespace DesignPatterns\Creational\AbstractFactory;
/** /**
* Class HtmlFactory * Class HtmlFactory

View File

@@ -1,8 +1,8 @@
<?php <?php
namespace DesignPatterns\AbstractFactory\Json; namespace DesignPatterns\Creational\AbstractFactory\Json;
use DesignPatterns\AbstractFactory\Picture as BasePicture; use DesignPatterns\Creational\AbstractFactory\Picture as BasePicture;
/** /**
* Class Picture * Class Picture

View File

@@ -1,8 +1,8 @@
<?php <?php
namespace DesignPatterns\AbstractFactory\Json; namespace DesignPatterns\Creational\AbstractFactory\Json;
use DesignPatterns\AbstractFactory\Text as BaseText; use DesignPatterns\Creational\AbstractFactory\Text as BaseText;
/** /**
* Class Text * Class Text

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\AbstractFactory; namespace DesignPatterns\Creational\AbstractFactory;
/** /**
* Class JsonFactory * Class JsonFactory

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\AbstractFactory; namespace DesignPatterns\Creational\AbstractFactory;
/** /**
* Interface MediaInterface * Interface MediaInterface

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\AbstractFactory; namespace DesignPatterns\Creational\AbstractFactory;
/** /**
* Class Picture * Class Picture

View File

@@ -1,10 +1,10 @@
<?php <?php
namespace DesignPatterns\Tests\AbstractFactory; namespace DesignPatterns\Creational\AbstractFactory\Tests;
use DesignPatterns\AbstractFactory\AbstractFactory; use DesignPatterns\Creational\AbstractFactory\AbstractFactory;
use DesignPatterns\AbstractFactory\HtmlFactory; use DesignPatterns\Creational\AbstractFactory\HtmlFactory;
use DesignPatterns\AbstractFactory\JsonFactory; use DesignPatterns\Creational\AbstractFactory\JsonFactory;
/** /**
* AbstractFactoryTest tests concrete factories * AbstractFactoryTest tests concrete factories
@@ -34,7 +34,7 @@ class AbstractFactoryTest extends \PHPUnit_Framework_TestCase
$factory->createText('footnotes') $factory->createText('footnotes')
); );
$this->assertContainsOnly('DesignPatterns\AbstractFactory\MediaInterface', $article); $this->assertContainsOnly('DesignPatterns\Creational\AbstractFactory\MediaInterface', $article);
/* this is the time to look at the Builder pattern. This pattern /* this is the time to look at the Builder pattern. This pattern
* helps you to create complex object like that article above with * helps you to create complex object like that article above with

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\AbstractFactory; namespace DesignPatterns\Creational\AbstractFactory;
/** /**
* Class Text * Class Text

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Builder; namespace DesignPatterns\Creational\Builder;
/** /**
* BikeBuilder builds bike * BikeBuilder builds bike

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Builder; namespace DesignPatterns\Creational\Builder;
/** /**
* *

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Builder; namespace DesignPatterns\Creational\Builder;
/** /**
* CarBuilder builds car * CarBuilder builds car

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Builder; namespace DesignPatterns\Creational\Builder;
/** /**
* Director is part of the builder pattern. It knows the interface of the builder * Director is part of the builder pattern. It knows the interface of the builder

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Builder\Parts; namespace DesignPatterns\Creational\Builder\Parts;
/** /**
* Bike is a bike * Bike is a bike

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Builder\Parts; namespace DesignPatterns\Creational\Builder\Parts;
/** /**
* Car is a car * Car is a car

View File

@@ -0,0 +1,11 @@
<?php
namespace DesignPatterns\Creational\Builder\Parts;
/**
* Class Door
*/
class Door
{
}

View File

@@ -0,0 +1,11 @@
<?php
namespace DesignPatterns\Creational\Builder\Parts;
/**
* Class Engine
*/
class Engine
{
}

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace DesignPatterns\Builder\Parts; namespace DesignPatterns\Creational\Builder\Parts;
/** /**
* VehicleInterface is a contract for a vehicle * VehicleInterface is a contract for a vehicle

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