From 3b7eb295c89bb6eec69b198bb58a5d40641afc2a Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Mon, 9 Sep 2013 10:39:41 +0200 Subject: [PATCH 01/28] cs AbstractFactory --- AbstractFactory/AbstractFactory.php | 2 ++ AbstractFactory/Html/Picture.php | 4 +--- AbstractFactory/Html/Text.php | 4 +--- AbstractFactory/HtmlFactory.php | 4 ++-- AbstractFactory/Json/Picture.php | 4 +--- AbstractFactory/Json/Text.php | 4 +--- AbstractFactory/JsonFactory.php | 4 ++-- .../{Media.php => MediaInterface.php} | 4 ++-- AbstractFactory/Picture.php | 2 +- AbstractFactory/Text.php | 2 +- .../{ElecBookAdapter.php => EBookAdapter.php} | 14 +++++++++----- Adapter/EBookInterface.php | 14 ++++++++++++++ Adapter/ElecBookInterface.php | 18 ------------------ Command/Command.php | 1 - Tests/AbstractFactory/AbstractFactoryTest.php | 10 ++-------- 15 files changed, 39 insertions(+), 52 deletions(-) rename AbstractFactory/{Media.php => MediaInterface.php} (85%) rename Adapter/{ElecBookAdapter.php => EBookAdapter.php} (71%) create mode 100644 Adapter/EBookInterface.php delete mode 100644 Adapter/ElecBookInterface.php diff --git a/AbstractFactory/AbstractFactory.php b/AbstractFactory/AbstractFactory.php index b3794d9..e322325 100644 --- a/AbstractFactory/AbstractFactory.php +++ b/AbstractFactory/AbstractFactory.php @@ -28,6 +28,7 @@ abstract class AbstractFactory * Creates a text component * * @param string $content + * * @return Text */ abstract public function createText($content); @@ -37,6 +38,7 @@ abstract class AbstractFactory * * @param string $path * @param string $name + * * @return Picture */ abstract public function createPicture($path, $name = ''); diff --git a/AbstractFactory/Html/Picture.php b/AbstractFactory/Html/Picture.php index c678cf1..2e648b0 100644 --- a/AbstractFactory/Html/Picture.php +++ b/AbstractFactory/Html/Picture.php @@ -11,7 +11,6 @@ use DesignPatterns\AbstractFactory\Picture as BasePicture; */ class Picture extends BasePicture { - /** * some crude rendering from HTML output * @@ -19,7 +18,6 @@ class Picture extends BasePicture */ public function render() { - return sprintf('', $this->_path, $this->_name); + return sprintf('', $this->path, $this->name); } - } diff --git a/AbstractFactory/Html/Text.php b/AbstractFactory/Html/Text.php index 4e626e2..8ea6d4f 100644 --- a/AbstractFactory/Html/Text.php +++ b/AbstractFactory/Html/Text.php @@ -11,7 +11,6 @@ use DesignPatterns\AbstractFactory\Text as BaseText; */ class Text extends BaseText { - /** * some crude rendering from HTML output * @@ -19,7 +18,6 @@ class Text extends BaseText */ public function render() { - return '
' . htmlspecialchars($this->_text) . '
'; + return '
' . htmlspecialchars($this->text) . '
'; } - } diff --git a/AbstractFactory/HtmlFactory.php b/AbstractFactory/HtmlFactory.php index dad71b9..3606374 100644 --- a/AbstractFactory/HtmlFactory.php +++ b/AbstractFactory/HtmlFactory.php @@ -9,12 +9,12 @@ namespace DesignPatterns\AbstractFactory; */ class HtmlFactory extends AbstractFactory { - /** * Creates a picture component * * @param string $path * @param string $name + * * @return Html\Picture|Picture */ public function createPicture($path, $name = '') @@ -26,11 +26,11 @@ class HtmlFactory extends AbstractFactory * Creates a text component * * @param string $content + * * @return Html\Text|Text */ public function createText($content) { return new Html\Text($content); } - } diff --git a/AbstractFactory/Json/Picture.php b/AbstractFactory/Json/Picture.php index 179aa3a..4684191 100644 --- a/AbstractFactory/Json/Picture.php +++ b/AbstractFactory/Json/Picture.php @@ -11,7 +11,6 @@ use DesignPatterns\AbstractFactory\Picture as BasePicture; */ class Picture extends BasePicture { - /** * some crude rendering from JSON output * @@ -19,7 +18,6 @@ class Picture extends BasePicture */ public function render() { - return json_encode(array('title' => $this->_name, 'path' => $this->_path)); + return json_encode(array('title' => $this->name, 'path' => $this->path)); } - } diff --git a/AbstractFactory/Json/Text.php b/AbstractFactory/Json/Text.php index 91115e8..83d0877 100644 --- a/AbstractFactory/Json/Text.php +++ b/AbstractFactory/Json/Text.php @@ -11,7 +11,6 @@ use DesignPatterns\AbstractFactory\Text as BaseText; */ class Text extends BaseText { - /** * some crude rendering from JSON output * @@ -19,7 +18,6 @@ class Text extends BaseText */ public function render() { - return json_encode(array('content' => $this->_text)); + return json_encode(array('content' => $this->text)); } - } diff --git a/AbstractFactory/JsonFactory.php b/AbstractFactory/JsonFactory.php index 814fbaf..6cf15d2 100644 --- a/AbstractFactory/JsonFactory.php +++ b/AbstractFactory/JsonFactory.php @@ -16,6 +16,7 @@ class JsonFactory extends AbstractFactory * * @param string $path * @param string $name + * * @return Json\Picture|Picture */ public function createPicture($path, $name = '') @@ -23,16 +24,15 @@ class JsonFactory extends AbstractFactory return new Json\Picture($path, $name); } - /** * Creates a text component * * @param string $content + * * @return Json\Text|Text */ public function createText($content) { return new Json\Text($content); } - } diff --git a/AbstractFactory/Media.php b/AbstractFactory/MediaInterface.php similarity index 85% rename from AbstractFactory/Media.php rename to AbstractFactory/MediaInterface.php index 53a66c1..16c5d78 100644 --- a/AbstractFactory/Media.php +++ b/AbstractFactory/MediaInterface.php @@ -3,12 +3,12 @@ namespace DesignPatterns\AbstractFactory; /** - * Interface Media + * Interface MediaInterface * * This contract is not part of the pattern, in general case, each component * are not related */ -interface Media +interface MediaInterface { /** diff --git a/AbstractFactory/Picture.php b/AbstractFactory/Picture.php index 6d9647e..264bfb6 100644 --- a/AbstractFactory/Picture.php +++ b/AbstractFactory/Picture.php @@ -5,7 +5,7 @@ namespace DesignPatterns\AbstractFactory; /** * Class Picture */ -abstract class Picture implements Media +abstract class Picture implements MediaInterface { /** diff --git a/AbstractFactory/Text.php b/AbstractFactory/Text.php index a45d7f2..675e6d5 100644 --- a/AbstractFactory/Text.php +++ b/AbstractFactory/Text.php @@ -5,7 +5,7 @@ namespace DesignPatterns\AbstractFactory; /** * Class Text */ -abstract class Text implements Media +abstract class Text implements MediaInterface { /** * @var string diff --git a/Adapter/ElecBookAdapter.php b/Adapter/EBookAdapter.php similarity index 71% rename from Adapter/ElecBookAdapter.php rename to Adapter/EBookAdapter.php index 49670af..c9ff06f 100644 --- a/Adapter/ElecBookAdapter.php +++ b/Adapter/EBookAdapter.php @@ -7,20 +7,22 @@ namespace DesignPatterns\Adapter; /** - * ElecBookAdapter is an adapter to fit an e-book like a paper book + * EBookAdapter is an adapter to fit an e-book like a paper book * * This is the adapter here. Notice it implemennts PaperBookInterface, * therefore you don't have to change the code of the client which using paper book. */ -class ElecBookAdapter implements PaperBookInterface +class EBookAdapter implements PaperBookInterface { protected $eBook; /** * Notice the constructor, it "wraps" an electronic book + * + * @param EBookInterface $ebook */ - public function __construct(ElecBookInterface $ebook) + public function __construct(EBookInterface $ebook) { $this->eBook = $ebook; } @@ -33,9 +35,11 @@ class ElecBookAdapter implements PaperBookInterface $this->eBook->pressStart(); } + /** + * turns pages + */ public function turnPage() { $this->eBook->pressNext(); } - -} \ No newline at end of file +} diff --git a/Adapter/EBookInterface.php b/Adapter/EBookInterface.php new file mode 100644 index 0000000..aa16221 --- /dev/null +++ b/Adapter/EBookInterface.php @@ -0,0 +1,14 @@ +createText('footnotes') ); - $this->assertContainsOnly('DesignPatterns\AbstractFactory\Media', $article); + $this->assertContainsOnly('DesignPatterns\AbstractFactory\MediaInterface', $article); + /* this is the time to look at the Builder pattern. This pattern * helps you to create complex object like that article above with * a given Abstract Factory */ - } - } \ No newline at end of file From 33671aec552c30f8798522b3d71c95d8b33130f8 Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Mon, 9 Sep 2013 10:50:00 +0200 Subject: [PATCH 02/28] cs Adapter --- Adapter/Book.php | 18 +++++++++--------- Adapter/EBookInterface.php | 1 - Adapter/Kindle.php | 22 ++++++++++------------ Adapter/PaperBookInterface.php | 21 +++++++++++++-------- Tests/Adapter/AdapterTest.php | 6 +++--- 5 files changed, 35 insertions(+), 33 deletions(-) diff --git a/Adapter/Book.php b/Adapter/Book.php index dcd3b0f..d993891 100644 --- a/Adapter/Book.php +++ b/Adapter/Book.php @@ -1,9 +1,5 @@ Date: Wed, 11 Sep 2013 16:06:03 +0200 Subject: [PATCH 03/28] cs Command --- Command/Command.php | 2 +- Command/HelloCommand.php | 16 +++++++++++----- Command/Invoker.php | 14 ++++++++++---- Command/Receiver.php | 7 ++++--- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/Command/Command.php b/Command/Command.php index ea10bb2..8fe9c5b 100644 --- a/Command/Command.php +++ b/Command/Command.php @@ -23,7 +23,7 @@ namespace DesignPatterns\Command; * can be implemented with the Command pattern (e.g. vagrant) * */ -interface Command +interface CommandInterface { /** * this is the most important method in the Command pattern, diff --git a/Command/HelloCommand.php b/Command/HelloCommand.php index 1ba3ecb..baaeda1 100644 --- a/Command/HelloCommand.php +++ b/Command/HelloCommand.php @@ -6,25 +6,31 @@ namespace DesignPatterns\Command; * This concrete command calls "print" on the Receiver, but an external * invoker just know he can call "execute" */ -class HelloCommand implements Command +class HelloCommand implements CommandInterface { - + /** + * @var Receiver + */ protected $output; /** * Each concrete command is builded with different receivers. - * Can be one, many, none or even other Command in parameters + * Can be one, many, none or even other Command in parameters + * + * @param Receiver $console */ public function __construct(Receiver $console) { $this->output = $console; } + /** + * execute and output "Hello World" + */ public function execute() { // sometimes, there is no receiver and this is the command which // does all the work $this->output->write('Hello World'); } - -} \ No newline at end of file +} diff --git a/Command/Invoker.php b/Command/Invoker.php index 75d7a23..f3013e6 100644 --- a/Command/Invoker.php +++ b/Command/Invoker.php @@ -12,23 +12,29 @@ namespace DesignPatterns\Command; */ class Invoker { - + /** + * @var CommandInterface + */ protected $command; /** * In the invoker we find this kind of method for subscribing the command. * There can be also a stack, a list, a fixed set... + * + * @param CommandInterface $cmd */ - public function setCommand(Command $cmd) + public function setCommand(CommandInterface $cmd) { $this->command = $cmd; } + /** + * executes the command + */ public function run() { // here is a key feature of the invoker // the invoker is the same whatever is the command $this->command->execute(); } - -} \ No newline at end of file +} diff --git a/Command/Receiver.php b/Command/Receiver.php index a9b6516..6fbed05 100644 --- a/Command/Receiver.php +++ b/Command/Receiver.php @@ -11,10 +11,11 @@ namespace DesignPatterns\Command; */ class Receiver { - + /** + * @param string $str + */ public function write($str) { echo $str; } - -} \ No newline at end of file +} From ed3bc7f2ecd8e898a04d7ca00a1dc1ab40d2c562 Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Wed, 11 Sep 2013 16:06:13 +0200 Subject: [PATCH 04/28] cs Adapter --- Adapter/EBookAdapter.php | 4 +++- Tests/Adapter/AdapterTest.php | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Adapter/EBookAdapter.php b/Adapter/EBookAdapter.php index c9ff06f..c572f67 100644 --- a/Adapter/EBookAdapter.php +++ b/Adapter/EBookAdapter.php @@ -14,7 +14,9 @@ namespace DesignPatterns\Adapter; */ class EBookAdapter implements PaperBookInterface { - + /** + * @var EBookInterface + */ protected $eBook; /** diff --git a/Tests/Adapter/AdapterTest.php b/Tests/Adapter/AdapterTest.php index 3e72ce7..7473de6 100644 --- a/Tests/Adapter/AdapterTest.php +++ b/Tests/Adapter/AdapterTest.php @@ -17,7 +17,9 @@ use DesignPatterns\Adapter\Book; */ class AdapterTest extends \PHPUnit_Framework_TestCase { - + /** + * @return array + */ public function getBook() { return array( @@ -30,7 +32,9 @@ class AdapterTest extends \PHPUnit_Framework_TestCase /** * This client only knows paper book but surprise, surprise, the second book * is in fact an electronic book, but both work the same way - * + * + * @param PaperBookInterface $book + * * @dataProvider getBook */ public function test_I_am_an_old_Client(PaperBookInterface $book) From 45ca69025bf7791c43e1cbd07a351ef9d0db9516 Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Wed, 11 Sep 2013 16:10:36 +0200 Subject: [PATCH 05/28] cs Composite --- Composite/Form.php | 17 +++++++++++++---- Composite/FormElement.php | 10 ++++++++++ Composite/InputElement.php | 10 ++++++++++ Composite/TextElement.php | 10 ++++++++++ 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/Composite/Form.php b/Composite/Form.php index 0cc16e1..decc599 100644 --- a/Composite/Form.php +++ b/Composite/Form.php @@ -3,7 +3,7 @@ namespace DesignPatterns\Composite; /** - * composite pattern + * Composite pattern * * Purpose: * to treat a group of objects the same way as a single instance of the object @@ -18,7 +18,10 @@ namespace DesignPatterns\Composite; */ class Form extends FormElement { - protected $_elements; + /** + * @var array|FormElement[] + */ + protected $elements; /** * runs through all elements and calls render() on them, then returns the complete representation @@ -26,20 +29,26 @@ class Form extends FormElement * * from the outside, one will not see this and the form will act like a single object instance * + * @param int $indent + * * @return string */ public function render($indent = 0) { $formCode = ''; - foreach ($this->_elements as $element) { + + foreach ($this->elements as $element) { $formCode .= $element->render($indent + 1) . PHP_EOL; } return $formCode; } + /** + * @param FormElement $element + */ public function addElement(FormElement $element) { - $this->_elements[] = $element; + $this->elements[] = $element; } } diff --git a/Composite/FormElement.php b/Composite/FormElement.php index 3e3de93..ab95c67 100644 --- a/Composite/FormElement.php +++ b/Composite/FormElement.php @@ -2,7 +2,17 @@ namespace DesignPatterns\Composite; +/** + * Class FormElement + */ abstract class FormElement { + /** + * renders the elements' code + * + * @param int $indent + * + * @return mixed + */ abstract public function render($indent = 0); } diff --git a/Composite/InputElement.php b/Composite/InputElement.php index 786df45..7a65241 100644 --- a/Composite/InputElement.php +++ b/Composite/InputElement.php @@ -2,8 +2,18 @@ namespace DesignPatterns\Composite; +/** + * Class InputElement + */ class InputElement extends FormElement { + /** + * renders the input element HTML + * + * @param int $indent + * + * @return mixed|string + */ public function render($indent = 0) { return str_repeat(' ', $indent) . ''; diff --git a/Composite/TextElement.php b/Composite/TextElement.php index c8214ca..9ea4a4e 100644 --- a/Composite/TextElement.php +++ b/Composite/TextElement.php @@ -2,8 +2,18 @@ namespace DesignPatterns\Composite; +/** + * Class TextElement + */ class TextElement extends FormElement { + /** + * renders the text element + * + * @param int $indent + * + * @return mixed|string + */ public function render($indent = 0) { return str_repeat(' ', $indent) . 'this is a text element'; From 9b3389ba4a6cd93d0829090a964e2d2837e618c8 Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Wed, 11 Sep 2013 16:13:08 +0200 Subject: [PATCH 06/28] cs DataMapper --- DataMapper/User.php | 45 ++++++++++++++++++++++----------------- DataMapper/UserMapper.php | 13 ++++++++--- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/DataMapper/User.php b/DataMapper/User.php index cd8afb1..12f8779 100644 --- a/DataMapper/User.php +++ b/DataMapper/User.php @@ -42,43 +42,48 @@ class User /** * @return int */ - public function getUserId() { - return $this->userId; - } + public function getUserId() + { + return $this->userId; + } /** * @param int $userId */ - public function setUserID($userId) { - $this->userId = $userId; - } + public function setUserID($userId) + { + $this->userId = $userId; + } /** * @return string */ - public function getUsername() { - return $this->username; - } + public function getUsername() + { + return $this->username; + } /** * @param string $username */ - public function setUsername($username) { - $this->username = $username; - } + public function setUsername($username) + { + $this->username = $username; + } /** * @return string */ - public function getEmail() { - return $this->email; - } + public function getEmail() + { + return $this->email; + } /** * @param string $email */ - public function setEmail($email) { - $this->email = $email; - } - -} \ No newline at end of file + public function setEmail($email) + { + $this->email = $email; + } +} diff --git a/DataMapper/UserMapper.php b/DataMapper/UserMapper.php index c7ee69f..0b6b689 100644 --- a/DataMapper/UserMapper.php +++ b/DataMapper/UserMapper.php @@ -25,12 +25,14 @@ namespace DesignPatterns\DataMapper; */ class UserMapper { - /** * @var DBAL */ protected $adapter; + /** + * @param DBAL $dbLayer + */ public function __construct(DBAL $dbLayer) { $this->adapter = $dbLayer; @@ -40,6 +42,7 @@ class UserMapper * saves a user object from memory to Database * * @param User $user + * * @return boolean */ public function save(User $user) @@ -55,9 +58,11 @@ class UserMapper if (null === ($id = $user->getUserId())) { unset($data['userid']); $this->adapter->insert($data); + return true; } else { $this->adapter->update($data, array('userid = ?' => $id)); + return true; } } @@ -66,13 +71,15 @@ class UserMapper * finds a user from Database based on ID and returns a User object located * in memory * - * @param $id + * @param int $id + * * @throws \InvalidArgumentException * @return User */ public function findById($id) { $result = $this->adapter->find($id); + if (0 == count($result)) { throw new \InvalidArgumentException("User #$id not found"); } @@ -104,7 +111,7 @@ class UserMapper * * @param array $row * - * @return \DesignPatterns\DataMapper\User + * @return User */ protected function mapObject(array $row) { From 79f94ba5014a9b89571260fabd51590d3028076f Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Wed, 11 Sep 2013 16:18:40 +0200 Subject: [PATCH 07/28] cs Decorator --- Command/{Command.php => CommandInterface.php} | 0 Decorator/Decorator.php | 17 +++++++------- Decorator/RenderInJson.php | 13 ++++++++--- Decorator/RenderInXml.php | 17 ++++++++++---- Decorator/Renderer.php | 9 -------- Decorator/RendererInterface.php | 16 ++++++++++++++ Decorator/Webservice.php | 22 ++++++++++++++----- Tests/Decorator/DecoratorTest.php | 4 ++-- 8 files changed, 66 insertions(+), 32 deletions(-) rename Command/{Command.php => CommandInterface.php} (100%) delete mode 100644 Decorator/Renderer.php create mode 100644 Decorator/RendererInterface.php diff --git a/Command/Command.php b/Command/CommandInterface.php similarity index 100% rename from Command/Command.php rename to Command/CommandInterface.php diff --git a/Decorator/Decorator.php b/Decorator/Decorator.php index 74d526d..88c1b84 100644 --- a/Decorator/Decorator.php +++ b/Decorator/Decorator.php @@ -16,24 +16,25 @@ namespace DesignPatterns\Decorator; */ /** - * the Deoorator MUST implement the Renderer contract, this is the key-feature + * the Deoorator MUST implement the RendererInterface contract, this is the key-feature * of this design pattern. If not, this is no longer a Decorator but just a dumb * wrapper. */ -abstract class Decorator implements Renderer +abstract class Decorator implements RendererInterface { - - protected $_wrapped; + /** + * @var RendererInterface + */ + protected $wrapped; /** * You must type-hint the wrapped component : * It ensures you can call renderData() in the subclasses ! * - * @param Renderer $wrappable + * @param RendererInterface $wrappable */ - public function __construct(Renderer $wrappable) + public function __construct(RendererInterface $wrappable) { - $this->_wrapped = $wrappable; + $this->wrapped = $wrappable; } } - diff --git a/Decorator/RenderInJson.php b/Decorator/RenderInJson.php index 0c521bd..0edc7ea 100644 --- a/Decorator/RenderInJson.php +++ b/Decorator/RenderInJson.php @@ -2,13 +2,20 @@ namespace DesignPatterns\Decorator; +/** + * Class RenderInJson + */ class RenderInJson extends Decorator { - + /** + * render data as JSON + * + * @return mixed|string + */ public function renderData() { - $output = $this->_wrapped->renderData(); + $output = $this->wrapped->renderData(); + return json_encode($output); } - } diff --git a/Decorator/RenderInXml.php b/Decorator/RenderInXml.php index 599c2f5..5967b98 100644 --- a/Decorator/RenderInXml.php +++ b/Decorator/RenderInXml.php @@ -2,19 +2,28 @@ namespace DesignPatterns\Decorator; +/** + * Class RenderInXml + */ class RenderInXml extends Decorator { - + /** + * render data as XML + * + * @return mixed|string + */ public function renderData() { - $output = $this->_wrapped->renderData(); - // do some fany conversion to xml from array ... + $output = $this->wrapped->renderData(); + + // do some fancy conversion to xml from array ... + $doc = new \DOMDocument(); + foreach ($output as $key => $val) { $doc->appendChild($doc->createElement('foo', 'bar')); } return $doc->saveXML(); } - } diff --git a/Decorator/Renderer.php b/Decorator/Renderer.php deleted file mode 100644 index af3c46b..0000000 --- a/Decorator/Renderer.php +++ /dev/null @@ -1,9 +0,0 @@ -_data = $data; + $this->data = $data; } + /** + * @return string + */ public function renderData() { - return $this->_data; + return $this->data; } - } diff --git a/Tests/Decorator/DecoratorTest.php b/Tests/Decorator/DecoratorTest.php index fce9e56..7f20bb6 100644 --- a/Tests/Decorator/DecoratorTest.php +++ b/Tests/Decorator/DecoratorTest.php @@ -42,7 +42,7 @@ class DecoratorTest extends \PHPUnit_Framework_TestCase */ public function testDecoratorMustImplementsRenderer() { - $this->assertTrue(is_subclass_of('DesignPatterns\Decorator\Decorator', 'DesignPatterns\Decorator\Renderer')); + $this->assertTrue(is_subclass_of('DesignPatterns\Decorator\Decorator', 'DesignPatterns\Decorator\RendererInterface')); } /** @@ -60,7 +60,7 @@ class DecoratorTest extends \PHPUnit_Framework_TestCase */ public function testDecoratorOnlyAcceptRenderer() { - $mock = $this->getMock('DesignPatterns\Decorator\Renderer'); + $mock = $this->getMock('DesignPatterns\Decorator\RendererInterface'); $dec = $this->getMockForAbstractClass('DesignPatterns\Decorator\Decorator', array($mock)); $this->assertNotNull($dec); } From 454382d8fbf72b691e02cb129118962037a218be Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Wed, 11 Sep 2013 16:21:26 +0200 Subject: [PATCH 08/28] cs DependencyInjection --- ...endencyInjection.php => Configuration.php} | 36 +++++-------------- DependencyInjection/Connection.php | 35 ++++++++++++++++++ 2 files changed, 44 insertions(+), 27 deletions(-) rename DependencyInjection/{DependencyInjection.php => Configuration.php} (57%) create mode 100644 DependencyInjection/Connection.php diff --git a/DependencyInjection/DependencyInjection.php b/DependencyInjection/Configuration.php similarity index 57% rename from DependencyInjection/DependencyInjection.php rename to DependencyInjection/Configuration.php index e4693e9..f972bb6 100644 --- a/DependencyInjection/DependencyInjection.php +++ b/DependencyInjection/Configuration.php @@ -1,6 +1,6 @@ _host = $host; + $this->host = $host; + return $this; // for a fluent interface } @@ -35,29 +40,6 @@ class Configuration */ public function getHost() { - return $this->_host; - } -} - -class Connection -{ - protected $_configuration; - - /** - * here, Configuration gets injected and Connection will get all that it needs from Configuration - * without DI, the configuration would be created directly in Connection, which is not very good - * for testing and extending Connection - * - * @param Configuration $config - */ - public function __construct(Configuration $config) - { - $this->_configuration = $config; - } - - public function connect() - { - $host = $this->_configuration->getHost(); - // ... + return $this->host; } } diff --git a/DependencyInjection/Connection.php b/DependencyInjection/Connection.php new file mode 100644 index 0000000..02ff81b --- /dev/null +++ b/DependencyInjection/Connection.php @@ -0,0 +1,35 @@ +configuration = $config; + } + + /** + * connection using the injected config + */ + public function connect() + { + $host = $this->configuration->getHost(); + // ... + } +} From 754ea98fb25d5ad210263edf923573f7893d7418 Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Wed, 11 Sep 2013 16:28:06 +0200 Subject: [PATCH 09/28] cs Facade --- Facade/BiosInterface.php | 31 +++++++++++++++++++++++++++++++ Facade/Facade.php | 30 ++++++++++++++++++++---------- Facade/OsInterface.php | 14 ++++++++++++++ 3 files changed, 65 insertions(+), 10 deletions(-) create mode 100644 Facade/BiosInterface.php create mode 100644 Facade/OsInterface.php diff --git a/Facade/BiosInterface.php b/Facade/BiosInterface.php new file mode 100644 index 0000000..377651c --- /dev/null +++ b/Facade/BiosInterface.php @@ -0,0 +1,31 @@ +bios = $bios; - $this->opsys = $os; + $this->os = $os; } + /** + * turn on the system + */ public function turnOn() { $this->bios->execute(); $this->bios->waitForKeyPress(); - $this->bios->launch($this->opsys); + $this->bios->launch($this->os); } + /** + * turn off the system + */ public function turnOff() { - $this->opsys->halt(); + $this->os->halt(); $this->bios->powerDown(); } - -} \ No newline at end of file +} diff --git a/Facade/OsInterface.php b/Facade/OsInterface.php new file mode 100644 index 0000000..e81c7f1 --- /dev/null +++ b/Facade/OsInterface.php @@ -0,0 +1,14 @@ + Date: Wed, 11 Sep 2013 16:35:18 +0200 Subject: [PATCH 10/28] cs FactoryMethod --- FactoryMethod/Bicycle.php | 18 +++++++++++------- FactoryMethod/FactoryMethod.php | 7 +------ FactoryMethod/Ferrari.php | 16 +++++++++------- FactoryMethod/GermanFactory.php | 20 ++++++-------------- FactoryMethod/ItalianFactory.php | 17 ++++------------- FactoryMethod/Porsche.php | 22 ++++++++++++++-------- FactoryMethod/Vehicle.php | 12 ++++++------ 7 files changed, 51 insertions(+), 61 deletions(-) diff --git a/FactoryMethod/Bicycle.php b/FactoryMethod/Bicycle.php index 772dcdf..0c71ba2 100644 --- a/FactoryMethod/Bicycle.php +++ b/FactoryMethod/Bicycle.php @@ -1,9 +1,5 @@ color = $rgb; } - -} \ No newline at end of file +} diff --git a/FactoryMethod/FactoryMethod.php b/FactoryMethod/FactoryMethod.php index 3402bd6..89a3ba9 100644 --- a/FactoryMethod/FactoryMethod.php +++ b/FactoryMethod/FactoryMethod.php @@ -1,9 +1,5 @@ color = $rgb; } - -} \ No newline at end of file +} diff --git a/FactoryMethod/GermanFactory.php b/FactoryMethod/GermanFactory.php index a962c76..acbac40 100644 --- a/FactoryMethod/GermanFactory.php +++ b/FactoryMethod/GermanFactory.php @@ -1,39 +1,31 @@ addTuningAMG(); + return $obj; break; - default : throw new \InvalidArgumentException("$type is not a valid vehicle"); } } - -} \ No newline at end of file +} diff --git a/FactoryMethod/ItalianFactory.php b/FactoryMethod/ItalianFactory.php index db8514c..cb8338c 100644 --- a/FactoryMethod/ItalianFactory.php +++ b/FactoryMethod/ItalianFactory.php @@ -1,9 +1,5 @@ color = $rgb; } + /** + * although tuning by AMG is only offered for Mercedes Cars, + * this is a valid coding example ... + */ public function addTuningAMG() { - - } -} \ No newline at end of file + } +} diff --git a/FactoryMethod/Vehicle.php b/FactoryMethod/Vehicle.php index 180a349..591873d 100644 --- a/FactoryMethod/Vehicle.php +++ b/FactoryMethod/Vehicle.php @@ -1,9 +1,5 @@ Date: Wed, 11 Sep 2013 16:40:02 +0200 Subject: [PATCH 11/28] cs FluentInterface --- FluentInterface/SQL.php | 46 ++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/FluentInterface/SQL.php b/FluentInterface/SQL.php index 84034da..6074f70 100644 --- a/FluentInterface/SQL.php +++ b/FluentInterface/SQL.php @@ -11,56 +11,78 @@ namespace DesignPatterns\FluentInterface; * Examples: * - Doctrine2's QueryBuilder works something like that example class below * - PHPUnit uses fluent interfaces to build mock objects - * - Yii Framework: CDbCommand and CActiveRecord use this pattern too - * + * - Yii Framework: CDbCommand and CActiveRecord use this pattern, too */ class SQL { - protected $_fields = array(); - protected $_from = array(); - protected $_where = array(); + /** + * @var array + */ + protected $fields = array(); /** + * @var array + */ + protected $from = array(); + + /** + * @var array + */ + protected $where = array(); + + /** + * adds select fields * * @param array $fields + * * @return SQL */ public function select(array $fields = array()) { - $this->_fields = $fields; + $this->fields = $fields; + return $this; } /** + * adds a FROM clause * * @param string $table * @param string $alias + * * @return SQL */ public function from($table, $alias) { - $this->_from[] = $table . ' AS ' . $alias; + $this->from[] = $table . ' AS ' . $alias; + return $this; } /** + * adds a WHERE condition + * * @param string $condition + * * @return SQL */ public function where($condition) { - $this->_where[] = $condition; + $this->where[] = $condition; + return $this; } - + /** * Gets the query, just an example of building a query, * no check on consistency + * + * @return string */ public function getQuery() { - return 'SELECT ' . implode(',', $this->_fields) - . ' FROM ' . implode(',', $this->_from) - . ' WHERE ' . implode(' AND ', $this->_where); + return 'SELECT ' . implode(',', $this->fields) + . ' FROM ' . implode(',', $this->from) + . ' WHERE ' . implode(' AND ', $this->where); } } From af442a99807dabaf7d4eebb172ac24c86862e315 Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Wed, 11 Sep 2013 16:50:01 +0200 Subject: [PATCH 12/28] cs Iterator and Proxy & Status --- Iterator/CardGame.php | 23 +++++--- Iterator/Iterator.php | 17 ++++-- Proxy/Proxy.php | 94 --------------------------------- Proxy/Record.php | 59 +++++++++++++++++++++ Proxy/RecordProxy.php | 50 ++++++++++++++++++ StatusPattern/StatusPattern.php | 16 +++--- 6 files changed, 147 insertions(+), 112 deletions(-) delete mode 100644 Proxy/Proxy.php create mode 100644 Proxy/Record.php create mode 100644 Proxy/RecordProxy.php diff --git a/Iterator/CardGame.php b/Iterator/CardGame.php index f6dd081..4d5997a 100644 --- a/Iterator/CardGame.php +++ b/Iterator/CardGame.php @@ -1,14 +1,10 @@ number) || current($this->color); } - -} \ No newline at end of file +} diff --git a/Iterator/Iterator.php b/Iterator/Iterator.php index e218412..1e39db1 100644 --- a/Iterator/Iterator.php +++ b/Iterator/Iterator.php @@ -21,20 +21,29 @@ namespace DesignPatterns; */ class File { - protected $_rowset; + /** + * @var Rowset + */ + protected $rowset; - protected $_pathName; + /** + * @var string + */ + protected $pathName; + /** + * @param string $pathName + */ public function __construct($pathName) { - $this->_rowset = new Rowset($this); + $this->rowset = new Rowset($this); } public function process() { // this is the place to show how using an iterator, with foreach // See the CardGame.php file - $this->_rowset->process(); + $this->rowset->process(); } } diff --git a/Proxy/Proxy.php b/Proxy/Proxy.php deleted file mode 100644 index f035e1f..0000000 --- a/Proxy/Proxy.php +++ /dev/null @@ -1,94 +0,0 @@ -_data = $data; - } - - /** - * magic setter - * - * @param string $name - * @param mixed $value - * @return void - */ - public function __set($name, $value) - { - $this->_data[(string) $name] = $value; - } - - /** - * magic getter - * - * @param string $name - * @return mixed|null - */ - public function __get($name) - { - if (array_key_exists($name, $this->_data)) { - return $this->_data[(string) $name]; - } else { - return null; - } - } -} - -class RecordProxy extends Record -{ - /** - * @var bool - */ - protected $_isDirty = false; - - /** - * @var bool - */ - protected $_isInitialized = false; - - /** - * @param array - */ - public function __construct($data) - { - parent::__construct($data); - - // when the record has data, mark it as initialized - // since Record will hold our business logic, we don't want to - // implement this behaviour there, but instead in a new proxy class - // that extends the Record class - if (null !== $data) { - $this->_isInitialized = true; - $this->_isDirty = true; - } - } - - /** - * magic setter - * - * @param string $name - * @param mixed $value - * @return void - */ - public function __set($name, $value) - { - $this->_isDirty = true; - parent::__set($name, $value); - } -} diff --git a/Proxy/Record.php b/Proxy/Record.php new file mode 100644 index 0000000..194908e --- /dev/null +++ b/Proxy/Record.php @@ -0,0 +1,59 @@ +_data = (array) $data; + } + + /** + * magic setter + * + * @param string $name + * @param mixed $value + * + * @return void + */ + public function __set($name, $value) + { + $this->_data[(string) $name] = $value; + } + + /** + * magic getter + * + * @param string $name + * + * @return mixed|null + */ + public function __get($name) + { + if (array_key_exists($name, $this->_data)) { + return $this->_data[(string) $name]; + } else { + return null; + } + } +} diff --git a/Proxy/RecordProxy.php b/Proxy/RecordProxy.php new file mode 100644 index 0000000..00cc18c --- /dev/null +++ b/Proxy/RecordProxy.php @@ -0,0 +1,50 @@ +isInitialized = true; + $this->isDirty = true; + } + } + + /** + * magic setter + * + * @param string $name + * @param mixed $value + * + * @return void + */ + public function __set($name, $value) + { + $this->isDirty = true; + parent::__set($name, $value); + } +} \ No newline at end of file diff --git a/StatusPattern/StatusPattern.php b/StatusPattern/StatusPattern.php index 92d2585..6c12937 100644 --- a/StatusPattern/StatusPattern.php +++ b/StatusPattern/StatusPattern.php @@ -10,8 +10,10 @@ namespace DesignPatterns; */ interface OrderInterface { - - public function shipOrder(); + /** + * @return mixed + */ + public function shipOrder(); public function completeOrder(); @@ -100,9 +102,12 @@ class OrderFactory { // Client -Class OrderControler { - - public function shipAction($id) +class OrderController +{ + /** + * @param int $id + */ + public function shipAction($id) { $order = OrderFactory::getOrder($id); try { @@ -123,5 +128,4 @@ Class OrderControler { } // response to browser } - } From 032cc57cf6d0c6332701f9e1afec63ecab393b4f Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Thu, 12 Sep 2013 11:20:10 +0200 Subject: [PATCH 13/28] cs Visitor --- Tests/Visitor/VisitorTest.php | 2 +- Visitor/Group.php | 4 +-- Visitor/Role.php | 26 +++++++++---------- Visitor/RolePrintVisitor.php | 8 +++--- ...leVisitor.php => RoleVisitorInterface.php} | 5 ++-- Visitor/User.php | 3 --- 6 files changed, 20 insertions(+), 28 deletions(-) rename Visitor/{RoleVisitor.php => RoleVisitorInterface.php} (91%) diff --git a/Tests/Visitor/VisitorTest.php b/Tests/Visitor/VisitorTest.php index dfca346..a287ab0 100644 --- a/Tests/Visitor/VisitorTest.php +++ b/Tests/Visitor/VisitorTest.php @@ -39,7 +39,7 @@ class VisitorTest extends \PHPUnit_Framework_TestCase } /** - * @expectedException InvalidArgumentException + * @expectedException \InvalidArgumentException * @expectedExceptionMessage Mock */ public function testUnknownObject() diff --git a/Visitor/Group.php b/Visitor/Group.php index 972e95c..5d47d6a 100644 --- a/Visitor/Group.php +++ b/Visitor/Group.php @@ -3,11 +3,10 @@ namespace DesignPatterns\Visitor; /** - * An example of a Visitee : Group + * An example of a Visitor: Group */ class Group extends Role { - /** * @var string */ @@ -28,5 +27,4 @@ class Group extends Role { return "Group: " . $this->name; } - } diff --git a/Visitor/Role.php b/Visitor/Role.php index 6d72cc5..6f5a0c4 100644 --- a/Visitor/Role.php +++ b/Visitor/Role.php @@ -7,34 +7,34 @@ namespace DesignPatterns\Visitor; * * Purpose: * The Visitor Pattern lets you outsource operations on objects to other objects. The main reason to do this is to keep - * a seperation of concerns. But classes have to define an contract to allow visitors (the "accept" method in the example below). + * a separation of concerns. But classes have to define an contract to allow visitors (the "accept" method in the example below). * * The contract is an abstract class but you can have also a clean interface. - * In that case, each Visitee has to choose itself which method to invoke on the visitor. + * In that case, each Visitor has to choose itself which method to invoke on the visitor. */ abstract class Role { - /** - * This method handles a double dispatch based on the shortname of the Visitee - * + * 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 - * - * @param \DesignPatterns\Visitor\RoleVisitor $visitor + * + * @param \DesignPatterns\Visitor\RoleVisitorInterface $visitor + * + * @throws \InvalidArgumentException */ - public function accept(RoleVisitor $visitor) + public function accept(RoleVisitorInterface $visitor) { // this trick to simulate double-dispatch based on type-hinting - $fqcn = get_called_class(); - preg_match('#([^\\\\]+)$#', $fqcn, $extract); + $klass = get_called_class(); + preg_match('#([^\\\\]+)$#', $klass, $extract); $visitingMethod = 'visit' . $extract[1]; // this ensures strong typing with visitor interface, not some visitor objects - if (!method_exists(__NAMESPACE__ . '\RoleVisitor', $visitingMethod)) { - throw new \InvalidArgumentException("The visitor you provide cannot visit a $fqcn instance"); + if (!method_exists(__NAMESPACE__ . '\RoleVisitorInterface', $visitingMethod)) { + throw new \InvalidArgumentException("The visitor you provide cannot visit a $klass instance"); } call_user_func(array($visitor, $visitingMethod), $this); } - } diff --git a/Visitor/RolePrintVisitor.php b/Visitor/RolePrintVisitor.php index 24a8b1e..40d447f 100644 --- a/Visitor/RolePrintVisitor.php +++ b/Visitor/RolePrintVisitor.php @@ -7,11 +7,10 @@ namespace DesignPatterns\Visitor; * * An implementation of a concrete Visitor */ -class RolePrintVisitor implements RoleVisitor +class RolePrintVisitor implements RoleVisitorInterface { - /** - * @inheritdoc + * {@inheritdoc} */ public function visitGroup(Group $role) { @@ -19,11 +18,10 @@ class RolePrintVisitor implements RoleVisitor } /** - * @inheritdoc + * {@inheritdoc} */ public function visitUser(User $role) { echo "Role: " . $role->getName(); } - } diff --git a/Visitor/RoleVisitor.php b/Visitor/RoleVisitorInterface.php similarity index 91% rename from Visitor/RoleVisitor.php rename to Visitor/RoleVisitorInterface.php index 634024d..8c1852a 100644 --- a/Visitor/RoleVisitor.php +++ b/Visitor/RoleVisitorInterface.php @@ -13,9 +13,8 @@ namespace DesignPatterns\Visitor; * Note 2 : the visitor must not choose itself which method to * invoke, it is the Visitee that make this decision. */ -interface RoleVisitor +interface RoleVisitorInterface { - /** * Visit a User object * @@ -24,7 +23,7 @@ interface RoleVisitor public function visitUser(User $role); /** - * Visit a Group objet + * Visit a Group object * * @param \DesignPatterns\Visitor\Group $role */ diff --git a/Visitor/User.php b/Visitor/User.php index 3555933..f9291fa 100644 --- a/Visitor/User.php +++ b/Visitor/User.php @@ -9,7 +9,6 @@ namespace DesignPatterns\Visitor; */ class User extends Role { - /** * @var string */ @@ -30,6 +29,4 @@ class User extends Role { return "User " . $this->name; } - } - From 1c9a83bea195a313f3f5a17b101f7d01b15257c9 Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Thu, 12 Sep 2013 11:20:27 +0200 Subject: [PATCH 14/28] cs Iterator & Mediator --- Iterator/Iterator.php | 35 +++++++++++++++++++++------------- Mediator/MediatorInterface.php | 18 +++++++++++------ 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/Iterator/Iterator.php b/Iterator/Iterator.php index 1e39db1..d05fcc6 100644 --- a/Iterator/Iterator.php +++ b/Iterator/Iterator.php @@ -22,9 +22,9 @@ namespace DesignPatterns; class File { /** - * @var Rowset + * @var RowSet */ - protected $rowset; + protected $rowSet; /** * @var string @@ -36,26 +36,35 @@ class File */ public function __construct($pathName) { - $this->rowset = new Rowset($this); + $this->rowSet = new Rowset($this); } public function process() { // this is the place to show how using an iterator, with foreach // See the CardGame.php file - $this->rowset->process(); + $this->rowSet->process(); } } class Rowset implements \Iterator { - protected $_currentRow; + /** + * @var + */ + protected $currentRow; - protected $_file; + /** + * @var string + */ + protected $file; + /** + * @param string $file + */ public function __construct($file) { - $this->_file = $file; + $this->file = $file; } /** @@ -81,28 +90,28 @@ class Rowset implements \Iterator public function rewind() { - // seek to first line from $this->_file + // seek to first line from $this->file } public function next() { - // read the next line from $this->_file + // read the next line from $this->file if (!$eof) { $data = ''; // get the line - $this->_currentRow = new Row($data); + $this->currentRow = new Row($data); } else { - $this->_currentRow = null; + $this->currentRow = null; } } public function current() { - return $this->_currentRow; + return $this->currentRow; } public function valid() { - return null !== $this->_currentRow; + return null !== $this->currentRow; } public function key() diff --git a/Mediator/MediatorInterface.php b/Mediator/MediatorInterface.php index 019ad4e..15ea67b 100644 --- a/Mediator/MediatorInterface.php +++ b/Mediator/MediatorInterface.php @@ -1,9 +1,5 @@ Date: Thu, 12 Sep 2013 11:27:01 +0200 Subject: [PATCH 15/28] cs TemplateMethod --- TemplateMethod/BeachJourney.php | 11 +++----- .../{CityJouney.php => CityJourney.php} | 15 +++++------ TemplateMethod/Journey.php | 26 +++++++++---------- Tests/TemplateMethod/JourneyTest.php | 2 +- 4 files changed, 23 insertions(+), 31 deletions(-) rename TemplateMethod/{CityJouney.php => CityJourney.php} (52%) diff --git a/TemplateMethod/BeachJourney.php b/TemplateMethod/BeachJourney.php index cec7bab..6370ef2 100644 --- a/TemplateMethod/BeachJourney.php +++ b/TemplateMethod/BeachJourney.php @@ -1,9 +1,5 @@ buyAFlight(); $this->takePlane(); @@ -53,24 +48,27 @@ abstract class Journey */ protected function buyGift() { - } - // this method will be unknown by subclasses (better) + /** + * this method will be unknown by subclasses (better) + */ private function buyAFlight() { echo "Buying a flight\n"; } - // sbclasses will get access to this method but cannot override it and - // compromise this algorithm (warning : cause of cyclic depedencies) + /** + * sbclasses will get access to this method but cannot override it and + * compromise this algorithm (warning : cause of cyclic dependencies) + */ final protected function takePlane() { echo "Taking the plane\n"; } // A note regarding the keyword "final" : don't use it when you start coding : - // add it after you narrow and know exacly what change and what remain unchanged - // in this algorithm. + // add it after you narrow and know exactly what change and what remain unchanged + // in this algorithm. // [abstract] x [3 access] x [final] = 12 combinations, it can be hard ! -} \ No newline at end of file +} diff --git a/Tests/TemplateMethod/JourneyTest.php b/Tests/TemplateMethod/JourneyTest.php index fcfc4e6..bc87062 100644 --- a/Tests/TemplateMethod/JourneyTest.php +++ b/Tests/TemplateMethod/JourneyTest.php @@ -23,7 +23,7 @@ class JourneyTest extends \PHPUnit_Framework_TestCase public function testCity() { - $journey = new TemplateMethod\CityJouney(); + $journey = new TemplateMethod\CityJourney(); $this->expectOutputRegex('#drink#'); $journey->takeATrip(); } From 3808eab0a0d5682a4af1956415674a6a5435c657 Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Thu, 12 Sep 2013 11:37:03 +0200 Subject: [PATCH 16/28] cs Strategy --- Strategy/ComparatorInterface.php | 17 +++++ Strategy/DateComparator.php | 24 +++++++ Strategy/IdComparator.php | 21 ++++++ Strategy/ObjectCollection.php | 48 +++++++++++++ Strategy/Strategy.php | 111 ------------------------------- Strategy/index.php | 39 +++++++++++ 6 files changed, 149 insertions(+), 111 deletions(-) create mode 100644 Strategy/ComparatorInterface.php create mode 100644 Strategy/DateComparator.php create mode 100644 Strategy/IdComparator.php create mode 100644 Strategy/ObjectCollection.php delete mode 100644 Strategy/Strategy.php create mode 100644 Strategy/index.php diff --git a/Strategy/ComparatorInterface.php b/Strategy/ComparatorInterface.php new file mode 100644 index 0000000..468a614 --- /dev/null +++ b/Strategy/ComparatorInterface.php @@ -0,0 +1,17 @@ +elements = $elements; + } + + /** + * @return array + */ + public function sort() + { + $callback = array($this->comparator, 'compare'); + uasort($this->elements, $callback); + + return $this->elements; + } + + /** + * @param ComparatorInterface $comparator + * + * @return void + */ + public function setComparator(ComparatorInterface $comparator) + { + $this->comparator = $comparator; + } +} diff --git a/Strategy/Strategy.php b/Strategy/Strategy.php deleted file mode 100644 index 45187b7..0000000 --- a/Strategy/Strategy.php +++ /dev/null @@ -1,111 +0,0 @@ -_elements = $elements; - } - - /** - * @return array - */ - public function sort() - { - $callback = array($this->_comparator, 'compare'); - uasort($this->_elements, $callback); - - return $this->_elements; - } - - /** - * @param Comparator $comparator - * @return void - */ - public function setComparator(Comparator $comparator) - { - $this->_comparator = $comparator; - } -} - -class IdComparator implements Comparator -{ - public function compare($a, $b) - { - if ($a['id'] == $b['id']) { - return 0; - } else { - return $a['id'] < $b['id'] ? -1 : 1; - } - } -} - -class DateComparator implements Comparator -{ - public function compare($a, $b) - { - $aDate = strtotime($a['date']); - $bDate = strtotime($b['date']); - - if ($aDate == $bDate) { - return 0; - } else { - return $aDate < $bDate ? -1 : 1; - } - } -} - -$elements = array( - array( - 'id' => 2, - 'date' => '2011-01-01', - ), - array( - 'id' => 1, - 'date' => '2011-02-01' - ) -); - -$collection = new ObjectCollection($elements); -$collection->setComparator(new IdComparator()); -$collection->sort(); - -$collection->setComparator(new DateComparator()); -$collection->sort(); \ No newline at end of file diff --git a/Strategy/index.php b/Strategy/index.php new file mode 100644 index 0000000..d59819a --- /dev/null +++ b/Strategy/index.php @@ -0,0 +1,39 @@ + 2, + 'date' => '2011-01-01', + ), + array( + 'id' => 1, + 'date' => '2011-02-01' + ) +); + +$collection = new ObjectCollection($elements); +$collection->setComparator(new IdComparator()); +$collection->sort(); + +$collection->setComparator(new DateComparator()); +$collection->sort(); From daac491ef094379cccfbf4724640fec26d0bfcb5 Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Thu, 12 Sep 2013 11:43:30 +0200 Subject: [PATCH 17/28] cs StaticFactory --- State/State.php | 143 ++++++++++++++++++++++++++++++++ StaticFactory/FormatNumber.php | 7 +- StaticFactory/FormatString.php | 7 +- StaticFactory/Formatter.php | 7 +- StaticFactory/StaticFactory.php | 10 ++- StatusPattern/StatusPattern.php | 131 ----------------------------- 6 files changed, 164 insertions(+), 141 deletions(-) create mode 100644 State/State.php delete mode 100644 StatusPattern/StatusPattern.php diff --git a/State/State.php b/State/State.php new file mode 100644 index 0000000..6182812 --- /dev/null +++ b/State/State.php @@ -0,0 +1,143 @@ +order = $order; + } + + public function shipOrder() + { + $this->order['status'] = 'shipping'; + $this->order['updatedTime'] = time(); + + // Setting the new order status into database; + return $this->updateOrder($order); + } + + public function completeOrder() + { + //Can not complete the order which status is created, throw exception; + throw new \Exception('Can not complete the order which status is created!'); + } +} + +class ShippingOrder implements OrderInterface +{ + + private $order; + + public function __construct(array $order) + { + if (empty($order)) { + throw new \Exception('Order can not be empty!'); + } + $this->order = $order; + } + + public function shipOrder() + { + //Can not ship the order which status is shipping, throw exception; + throw new \Exception('Can not ship the order which status is shipping!'); + } + + public function completeOrder() + { + $this->order['status'] = 'completed'; + $this->order['updatedTime'] = time(); + + // Setting the new order status into database; + return $this->updateOrder($order); + } +} + +class OrderFactory +{ + + private function __construct() + { + throw Exception('Can not instance the OrderFactory class!'); + } + + public static function getOrder($id) + { + $order = 'Get Order From Database'; + + switch ($order['status']) { + case 'created': + return new CreateOrder($order); + case 'shipping': + return new ShippingOrder($order); + default: + throw new \Exception('Order status error!'); + break; + } + } +} + + +// Client + +class OrderController +{ + /** + * @param int $id + */ + public function shipAction($id) + { + $order = OrderFactory::getOrder($id); + try { + $order->shipOrder($id); + } catch (Exception $e) { + //handle error! + } + // response to browser + } + + public function completeAction($id) + { + $order = OrderFactory::getOrder($id); + try { + $order->completeOrder($id); + } catch (Exception $e) { + //handle error! + } + // response to browser + } +} diff --git a/StaticFactory/FormatNumber.php b/StaticFactory/FormatNumber.php index f7bf851..8b20db2 100644 --- a/StaticFactory/FormatNumber.php +++ b/StaticFactory/FormatNumber.php @@ -2,7 +2,10 @@ namespace DesignPatterns\StaticFactory; -class FormatNumber implements Formatter +/** + * Class FormatNumber + */ +class FormatNumber implements FormatterInterface { - + } diff --git a/StaticFactory/FormatString.php b/StaticFactory/FormatString.php index 9f961e7..9f48fde 100644 --- a/StaticFactory/FormatString.php +++ b/StaticFactory/FormatString.php @@ -2,7 +2,10 @@ namespace DesignPatterns\StaticFactory; -class FormatString implements Formatter +/** + * Class FormatString + */ +class FormatString implements FormatterInterface { - + } diff --git a/StaticFactory/Formatter.php b/StaticFactory/Formatter.php index 54b0ba0..b5220cd 100644 --- a/StaticFactory/Formatter.php +++ b/StaticFactory/Formatter.php @@ -2,7 +2,10 @@ namespace DesignPatterns\StaticFactory; -interface Formatter +/** + * Class FormatterInterface + */ +interface FormatterInterface { - + } diff --git a/StaticFactory/StaticFactory.php b/StaticFactory/StaticFactory.php index aa32d43..f31d4a1 100644 --- a/StaticFactory/StaticFactory.php +++ b/StaticFactory/StaticFactory.php @@ -14,16 +14,19 @@ namespace DesignPatterns\StaticFactory; * - Zend Framework: Zend_Cache_Backend or _Frontend use a factory method create cache backends or frontends * * Note1: Remember, static => global => evil - * Note2: Cannot be subclassed or mock-uped or have multiple different instances + * Note2: Cannot be subclassed or mock-upped or have multiple different instances */ class StaticFactory { - /** * the parametrized function to get create an instance * + * @param string $type + * * @static - * @return Formatter + * + * @throws \InvalidArgumentException + * @return FormatterInterface */ public static function factory($type) { @@ -35,5 +38,4 @@ class StaticFactory return new $className(); } - } diff --git a/StatusPattern/StatusPattern.php b/StatusPattern/StatusPattern.php deleted file mode 100644 index 6c12937..0000000 --- a/StatusPattern/StatusPattern.php +++ /dev/null @@ -1,131 +0,0 @@ -order = $order; - } - - public function shipOrder() - { - $this->order['status'] = 'shipping'; - $this->order['updatedTime'] = time(); - // Setting the new order status into database; - return $this->updateOrder($order); - } - - public function completeOrder() - { - //Can not complete the order which status is created, throw exception; - throw new \Exception('Can not complete the order which status is created!'); - } -} - -class ShippingOrder implements OrderInterface -{ - - private $order; - - public function __construct(array $order) - { - if (empty($order)) { - throw new \Exception('Order can not be empty!'); - } - $this->order = $order; - } - - public function shipOrder() - { - //Can not ship the order which status is shipping, throw exception; - throw new \Exception('Can not ship the order which status is shipping!'); - } - - public function completeOrder() - { - $this->order['status'] = 'completed'; - $this->order['updatedTime'] = time(); - // Setting the new order status into database; - return $this->updateOrder($order); - } -} - - -class OrderFactory { - - public static function getOrder($id) - { - $order = 'Get Order From Database'; - - switch ($order['status']) { - case 'created': - return new CreateOrder($order); - case 'shipping': - return new ShippingOrder($order); - default: - throw new \Exception('Order status error!'); - break; - } - } - - private function __construct() - { - throw Exception('Can not instance the OrderFactory class!'); - } -} - - -// Client - -class OrderController -{ - /** - * @param int $id - */ - public function shipAction($id) - { - $order = OrderFactory::getOrder($id); - try { - $order->shipOrder($id); - } catch (Exception $e) { - //handle error! - } - // response to browser - } - - public function completeAction($id) - { - $order = OrderFactory::getOrder($id); - try { - $order->completeOrder($id); - } catch (Exception $e) { - //handle error! - } - // response to browser - } -} From ec6ed14767de1762986d11be69fd2f20ec45d540 Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Thu, 12 Sep 2013 11:46:14 +0200 Subject: [PATCH 18/28] cs --- Command/HelloCommand.php | 2 +- FactoryMethod/GermanFactory.php | 2 +- FactoryMethod/ItalianFactory.php | 2 +- Singleton/Singleton.php | 12 +++++++++--- Tests/bootstrap.php | 10 +++++----- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/Command/HelloCommand.php b/Command/HelloCommand.php index baaeda1..9bb0956 100644 --- a/Command/HelloCommand.php +++ b/Command/HelloCommand.php @@ -29,7 +29,7 @@ class HelloCommand implements CommandInterface */ public function execute() { - // sometimes, there is no receiver and this is the command which + // sometimes, there is no receiver and this is the command which // does all the work $this->output->write('Hello World'); } diff --git a/FactoryMethod/GermanFactory.php b/FactoryMethod/GermanFactory.php index acbac40..36e7f04 100644 --- a/FactoryMethod/GermanFactory.php +++ b/FactoryMethod/GermanFactory.php @@ -24,7 +24,7 @@ class GermanFactory extends FactoryMethod return $obj; break; - default : + default: throw new \InvalidArgumentException("$type is not a valid vehicle"); } } diff --git a/FactoryMethod/ItalianFactory.php b/FactoryMethod/ItalianFactory.php index cb8338c..17a1233 100644 --- a/FactoryMethod/ItalianFactory.php +++ b/FactoryMethod/ItalianFactory.php @@ -19,7 +19,7 @@ class ItalianFactory extends FactoryMethod case parent::FAST: return new Ferrari(); break; - default : + default: throw new \InvalidArgumentException("$type is not a valid vehicle"); } } diff --git a/Singleton/Singleton.php b/Singleton/Singleton.php index 3a42582..e47579a 100644 --- a/Singleton/Singleton.php +++ b/Singleton/Singleton.php @@ -40,7 +40,9 @@ class Singleton * */ private function __construct() - {} + { + + } /** * prevent the instance from being cloned @@ -48,7 +50,9 @@ class Singleton * @return void */ private function __clone() - {} + { + + } /** * prevent from being unserialized @@ -56,5 +60,7 @@ class Singleton * @return void */ private function __wakeup() - {} + { + + } } diff --git a/Tests/bootstrap.php b/Tests/bootstrap.php index 78d586e..4a725a2 100644 --- a/Tests/bootstrap.php +++ b/Tests/bootstrap.php @@ -1,8 +1,8 @@ Date: Fri, 13 Sep 2013 11:47:46 +0200 Subject: [PATCH 19/28] cs SimpleFactory and Builder --- Builder/Parts/Vehicle.php | 2 +- SimpleFactory/Bicycle.php | 2 +- SimpleFactory/ConcreteFactory.php | 2 +- SimpleFactory/Scooter.php | 15 ++++++--------- SimpleFactory/Vehicle.php | 16 ---------------- SimpleFactory/VehicleInterface.php | 16 ++++++++++++++++ .../{Formatter.php => FormatterInterface.php} | 0 Tests/SimpleFactory/SimpleFactoryTest.php | 2 +- Tests/StaticFactory/StaticFactoryTest.php | 2 +- 9 files changed, 27 insertions(+), 30 deletions(-) delete mode 100644 SimpleFactory/Vehicle.php create mode 100644 SimpleFactory/VehicleInterface.php rename StaticFactory/{Formatter.php => FormatterInterface.php} (100%) diff --git a/Builder/Parts/Vehicle.php b/Builder/Parts/Vehicle.php index 7f627b7..15c39c0 100644 --- a/Builder/Parts/Vehicle.php +++ b/Builder/Parts/Vehicle.php @@ -7,7 +7,7 @@ namespace DesignPatterns\Builder\Parts; /** - * Vehicle is a contract for a vehicle + * VehicleInterface is a contract for a vehicle */ abstract class Vehicle { diff --git a/SimpleFactory/Bicycle.php b/SimpleFactory/Bicycle.php index 39c2d32..50f1415 100644 --- a/SimpleFactory/Bicycle.php +++ b/SimpleFactory/Bicycle.php @@ -9,7 +9,7 @@ namespace DesignPatterns\SimpleFactory; /** * Bicycle is a bicycle */ -class Bicycle implements Vehicle +class Bicycle implements VehicleInterface { public function driveTo($destination) diff --git a/SimpleFactory/ConcreteFactory.php b/SimpleFactory/ConcreteFactory.php index 01ba1ad..fa9f4ad 100644 --- a/SimpleFactory/ConcreteFactory.php +++ b/SimpleFactory/ConcreteFactory.php @@ -36,7 +36,7 @@ class ConcreteFactory * Creates a vehicle * * @param string $type a known type key - * @return Vehicle a new instance of Vehicle + * @return VehicleInterface a new instance of VehicleInterface * @throws \InvalidArgumentException */ public function createVehicle($type) diff --git a/SimpleFactory/Scooter.php b/SimpleFactory/Scooter.php index 925d7d2..2e386b7 100644 --- a/SimpleFactory/Scooter.php +++ b/SimpleFactory/Scooter.php @@ -1,20 +1,17 @@ factory->createVehicle($type); - $this->assertInstanceOf('DesignPatterns\SimpleFactory\Vehicle', $obj); + $this->assertInstanceOf('DesignPatterns\SimpleFactory\VehicleInterface', $obj); } /** diff --git a/Tests/StaticFactory/StaticFactoryTest.php b/Tests/StaticFactory/StaticFactoryTest.php index e906705..65087f5 100644 --- a/Tests/StaticFactory/StaticFactoryTest.php +++ b/Tests/StaticFactory/StaticFactoryTest.php @@ -25,7 +25,7 @@ class StaticFactoryTest extends \PHPUnit_Framework_TestCase public function testCreation($type) { $obj = StaticFactory::factory($type); - $this->assertInstanceOf('DesignPatterns\StaticFactory\Formatter', $obj); + $this->assertInstanceOf('DesignPatterns\StaticFactory\FormatterInterface', $obj); } } From 644d9cbd49c602e95fea3fef49103aeeb17a0bcf Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Fri, 13 Sep 2013 12:00:39 +0200 Subject: [PATCH 20/28] cs --- NullObject/LoggerInterface.php | 14 ++++++------- NullObject/NullLogger.php | 11 ++++------ NullObject/PrintLogger.php | 11 ++++------ NullObject/Service.php | 20 +++++++++++------- Observer/User.php | 35 ++++++++++++++++++------------- Observer/UserObserver.php | 2 -- Proxy/Record.php | 10 ++++----- Proxy/RecordProxy.php | 2 +- Registry/Registry.php | 26 +++++++++++++++-------- SimpleFactory/Bicycle.php | 15 +++++++------ SimpleFactory/ConcreteFactory.php | 12 +++++------ Tests/Observer/ObserverTest.php | 6 +++--- 12 files changed, 86 insertions(+), 78 deletions(-) diff --git a/NullObject/LoggerInterface.php b/NullObject/LoggerInterface.php index 2cb19d0..9acf855 100644 --- a/NullObject/LoggerInterface.php +++ b/NullObject/LoggerInterface.php @@ -1,18 +1,18 @@ logger = $log; } + /** + * do something ... + */ public function doSomething() { // no more check "if (!is_null($this->logger))..." with the NullObject pattern $this->logger->log('We are in ' . __METHOD__); // something to do... } - -} \ No newline at end of file +} diff --git a/Observer/User.php b/Observer/User.php index 3b41867..3ee3fba 100644 --- a/Observer/User.php +++ b/Observer/User.php @@ -10,49 +10,57 @@ namespace DesignPatterns\Observer; */ class User implements \SplSubject { - - protected $_data = array(); - /** + * user data + * * @var array */ - protected $_observers = array(); + protected $data = array(); + + /** + * observers + * + * @var array + */ + protected $observers = array(); /** * attach a new observer * * @param \SplObserver $observer + * * @return void */ public function attach(\SplObserver $observer) { - $this->_observers[] = $observer; + $this->observers[] = $observer; } /** * detach an observer * * @param \SplObserver $observer + * * @return void */ public function detach(\SplObserver $observer) { - $index = array_search($observer, $this->_observers); + $index = array_search($observer, $this->observers); if (false !== $index) { - unset($this->_observers[$index]); + unset($this->observers[$index]); } } /** - * + * notify observers * * @return void */ public function notify() { /** @var SplObserver $observer */ - foreach ($this->_observers as $observer) { + foreach ($this->observers as $observer) { $observer->update($this); } } @@ -61,17 +69,16 @@ class User implements \SplSubject * Ideally one would better write setter/getter for all valid attributes and only call notify() * on attributes that matter when changed * - * @param $name - * @param $value + * @param string $name + * @param mixed $value + * * @return void */ public function __set($name, $value) { - $this->_data[$name] = $value; + $this->data[$name] = $value; // notify the observers, that user has been updated $this->notify(); } - } - diff --git a/Observer/UserObserver.php b/Observer/UserObserver.php index 3cb8b9a..549da20 100644 --- a/Observer/UserObserver.php +++ b/Observer/UserObserver.php @@ -17,7 +17,6 @@ namespace DesignPatterns\Observer; */ class UserObserver implements \SplObserver { - /** * This is the only method to implement as an observer. * It is called by the Subject (usually by SplSubject::notify() ) @@ -28,5 +27,4 @@ class UserObserver implements \SplObserver { echo get_class($subject) . ' has been updated'; } - } diff --git a/Proxy/Record.php b/Proxy/Record.php index 194908e..722d946 100644 --- a/Proxy/Record.php +++ b/Proxy/Record.php @@ -18,14 +18,14 @@ class Record /** * @var array|null */ - protected $_data; + protected $data; /** * @param null $data */ public function __construct($data = null) { - $this->_data = (array) $data; + $this->data = (array) $data; } /** @@ -38,7 +38,7 @@ class Record */ public function __set($name, $value) { - $this->_data[(string) $name] = $value; + $this->data[(string) $name] = $value; } /** @@ -50,8 +50,8 @@ class Record */ public function __get($name) { - if (array_key_exists($name, $this->_data)) { - return $this->_data[(string) $name]; + if (array_key_exists($name, $this->data)) { + return $this->data[(string) $name]; } else { return null; } diff --git a/Proxy/RecordProxy.php b/Proxy/RecordProxy.php index 00cc18c..63f7904 100644 --- a/Proxy/RecordProxy.php +++ b/Proxy/RecordProxy.php @@ -47,4 +47,4 @@ class RecordProxy extends Record $this->isDirty = true; parent::__set($name, $value); } -} \ No newline at end of file +} diff --git a/Registry/Registry.php b/Registry/Registry.php index ea96491..65509c0 100644 --- a/Registry/Registry.php +++ b/Registry/Registry.php @@ -14,39 +14,47 @@ namespace DesignPatterns; * - Yii Framework: CWebApplication holds all the application components, such as CWebUser, CUrlManager, etc. * */ - abstract class Registry { const LOGGER = 'logger'; - protected static $_storedValues; + /** + * @var array + */ + protected static $storedValues = array(); /** - * @static + * sets a value + * * @param string $key - * @param mixed $value + * @param mixed $value + * + * @static * @return void */ public static function set($key, $value) { - self::$_storedValues[$key] = $value; + self::$storedValues[$key] = $value; } /** - * @static + * gets a value from the registry + * * @param string $key + * + * @static * @return mixed */ public static function get($key) { - return self::$_storedValues[$key]; + return self::$storedValues[$key]; } // typically there would be methods to check if a key has already been registered and so on ... } -// while bootstraping the application +// while bootstrapping the application Registry::set(Registry::LOGGER, new \StdClass()); // throughout the application -Registry::get(Registry::LOGGER)->log('foo'); \ No newline at end of file +Registry::get(Registry::LOGGER)->log('foo'); diff --git a/SimpleFactory/Bicycle.php b/SimpleFactory/Bicycle.php index 50f1415..fbe605d 100644 --- a/SimpleFactory/Bicycle.php +++ b/SimpleFactory/Bicycle.php @@ -1,9 +1,5 @@ assertAttributeEmpty('_observers', $subject); + $this->assertAttributeEmpty('observers', $subject); $subject->attach($this->observer); - $this->assertAttributeNotEmpty('_observers', $subject); + $this->assertAttributeNotEmpty('observers', $subject); $subject->detach($this->observer); - $this->assertAttributeEmpty('_observers', $subject); + $this->assertAttributeEmpty('observers', $subject); } /** From 8452c63b7ed6d7ebb94853491010f3f0bf8cc89d Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Fri, 13 Sep 2013 14:05:31 +0200 Subject: [PATCH 21/28] cs State --- State/CreateOrder.php | 49 +++++++++++++ State/OrderController.php | 37 ++++++++++ State/OrderFactory.php | 35 ++++++++++ State/OrderInterface.php | 19 +++++ State/ShippingOrder.php | 49 +++++++++++++ State/State.php | 143 -------------------------------------- 6 files changed, 189 insertions(+), 143 deletions(-) create mode 100644 State/CreateOrder.php create mode 100644 State/OrderController.php create mode 100644 State/OrderFactory.php create mode 100644 State/OrderInterface.php create mode 100644 State/ShippingOrder.php delete mode 100644 State/State.php diff --git a/State/CreateOrder.php b/State/CreateOrder.php new file mode 100644 index 0000000..eb494cc --- /dev/null +++ b/State/CreateOrder.php @@ -0,0 +1,49 @@ +order = $order; + } + + /** + * @return mixed + */ + public function shipOrder() + { + $this->order['status'] = 'shipping'; + $this->order['updatedTime'] = time(); + + // Setting the new order status into database; + return $this->updateOrder($order); + } + + /** + * @return mixed|void + * @throws \Exception + */ + public function completeOrder() + { + //Can not complete the order which status is created, throw exception; + throw new \Exception('Can not complete the order which status is created!'); + } +} diff --git a/State/OrderController.php b/State/OrderController.php new file mode 100644 index 0000000..a9690b4 --- /dev/null +++ b/State/OrderController.php @@ -0,0 +1,37 @@ +shipOrder($id); + } catch (Exception $e) { + //handle error! + } + // response to browser + } + + /** + * @param int $id + */ + public function completeAction($id) + { + $order = OrderFactory::getOrder($id); + try { + $order->completeOrder($id); + } catch (Exception $e) { + //handle error! + } + // response to browser + } +} diff --git a/State/OrderFactory.php b/State/OrderFactory.php new file mode 100644 index 0000000..55c7d80 --- /dev/null +++ b/State/OrderFactory.php @@ -0,0 +1,35 @@ +order = $order; + } + + /** + * @return mixed|void + * @throws \Exception + */ + public function shipOrder() + { + //Can not ship the order which status is shipping, throw exception; + throw new \Exception('Can not ship the order which status is shipping!'); + } + + /** + * @return mixed + */ + public function completeOrder() + { + $this->order['status'] = 'completed'; + $this->order['updatedTime'] = time(); + + // Setting the new order status into database; + return $this->updateOrder($order); + } +} diff --git a/State/State.php b/State/State.php deleted file mode 100644 index 6182812..0000000 --- a/State/State.php +++ /dev/null @@ -1,143 +0,0 @@ -order = $order; - } - - public function shipOrder() - { - $this->order['status'] = 'shipping'; - $this->order['updatedTime'] = time(); - - // Setting the new order status into database; - return $this->updateOrder($order); - } - - public function completeOrder() - { - //Can not complete the order which status is created, throw exception; - throw new \Exception('Can not complete the order which status is created!'); - } -} - -class ShippingOrder implements OrderInterface -{ - - private $order; - - public function __construct(array $order) - { - if (empty($order)) { - throw new \Exception('Order can not be empty!'); - } - $this->order = $order; - } - - public function shipOrder() - { - //Can not ship the order which status is shipping, throw exception; - throw new \Exception('Can not ship the order which status is shipping!'); - } - - public function completeOrder() - { - $this->order['status'] = 'completed'; - $this->order['updatedTime'] = time(); - - // Setting the new order status into database; - return $this->updateOrder($order); - } -} - -class OrderFactory -{ - - private function __construct() - { - throw Exception('Can not instance the OrderFactory class!'); - } - - public static function getOrder($id) - { - $order = 'Get Order From Database'; - - switch ($order['status']) { - case 'created': - return new CreateOrder($order); - case 'shipping': - return new ShippingOrder($order); - default: - throw new \Exception('Order status error!'); - break; - } - } -} - - -// Client - -class OrderController -{ - /** - * @param int $id - */ - public function shipAction($id) - { - $order = OrderFactory::getOrder($id); - try { - $order->shipOrder($id); - } catch (Exception $e) { - //handle error! - } - // response to browser - } - - public function completeAction($id) - { - $order = OrderFactory::getOrder($id); - try { - $order->completeOrder($id); - } catch (Exception $e) { - //handle error! - } - // response to browser - } -} From 8b82ed198da13d46541c52ef365b65e401e563ac Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Fri, 13 Sep 2013 14:19:55 +0200 Subject: [PATCH 22/28] cs --- Adapter/EBookAdapter.php | 4 --- Builder/BikeBuilder.php | 4 --- Builder/Builder.php | 32 ++++++++++++------- Builder/CarBuilder.php | 7 +--- Builder/Director.php | 4 --- Builder/Parts/Bike.php | 8 ++--- Builder/Parts/Car.php | 8 ++--- Builder/Parts/Door.php | 7 ++-- Builder/Parts/Engine.php | 7 ++-- Builder/Parts/Vehicle.php | 15 +++++---- .../ChainOfResponsibilities.php | 2 +- ChainOfResponsibilities/Handler.php | 10 +++--- ChainOfResponsibilities/Request.php | 6 +--- .../Responsible/FastStorage.php | 5 --- .../Responsible/SlowStorage.php | 13 ++++---- Command/Invoker.php | 4 --- Command/Receiver.php | 4 --- FactoryMethod/Bicycle.php | 2 +- FactoryMethod/FactoryMethod.php | 4 +-- FactoryMethod/Ferrari.php | 2 +- FactoryMethod/Porsche.php | 2 +- .../{Vehicle.php => VehicleInterface.php} | 6 ++-- Mediator/Colleague.php | 17 +++++----- Mediator/Mediator.php | 4 --- Mediator/Subsystem/Client.php | 6 +--- Mediator/Subsystem/Database.php | 6 +--- Mediator/Subsystem/Server.php | 7 +--- State/OrderFactory.php | 2 +- Tests/AbstractFactory/AbstractFactoryTest.php | 2 +- Tests/Adapter/AdapterTest.php | 7 +--- Tests/Builder/DirectorTest.php | 7 +--- Tests/ChainOfResponsibilities/ChainTest.php | 7 +--- Tests/Command/CommandTest.php | 7 +--- Tests/Composite/FormTest.php | 7 +--- Tests/DataMapper/UserMapperTest.php | 5 --- Tests/Decorator/DecoratorTest.php | 7 +--- Tests/Facade/FacadeTest.php | 7 +--- Tests/FactoryMethod/FactoryMethodTest.php | 9 ++---- Tests/FluentInterface/FluentInterfaceTest.php | 7 +--- Tests/Iterator/IteratorTest.php | 7 +--- Tests/Mediator/MediatorTest.php | 7 +--- Tests/NullObject/LoggerTest.php | 7 +--- Tests/SimpleFactory/SimpleFactoryTest.php | 4 --- Tests/Singleton/SingletonTest.php | 7 +--- Tests/StaticFactory/StaticFactoryTest.php | 1 - Tests/TemplateMethod/JourneyTest.php | 4 --- Tests/Visitor/VisitorTest.php | 4 --- 47 files changed, 93 insertions(+), 218 deletions(-) rename FactoryMethod/{Vehicle.php => VehicleInterface.php} (56%) diff --git a/Adapter/EBookAdapter.php b/Adapter/EBookAdapter.php index c572f67..9677553 100644 --- a/Adapter/EBookAdapter.php +++ b/Adapter/EBookAdapter.php @@ -1,9 +1,5 @@ car; } - -} \ No newline at end of file +} diff --git a/Builder/Director.php b/Builder/Director.php index 7a55a0d..32ffaa7 100644 --- a/Builder/Director.php +++ b/Builder/Director.php @@ -1,9 +1,5 @@ data[$key] = $value; } - -} \ No newline at end of file +} diff --git a/ChainOfResponsibilities/ChainOfResponsibilities.php b/ChainOfResponsibilities/ChainOfResponsibilities.php index 5b2686d..257f7c9 100644 --- a/ChainOfResponsibilities/ChainOfResponsibilities.php +++ b/ChainOfResponsibilities/ChainOfResponsibilities.php @@ -93,4 +93,4 @@ $fastStorage->get('bar'); // will be handled by FastStorage /** * In this example we could also add a abstract class and extend it to build Fast- and SlowStorage. That class would * then manage the chain and when the cache hits a "miss", it would check if there is a next handler - */ \ No newline at end of file + */ diff --git a/ChainOfResponsibilities/Handler.php b/ChainOfResponsibilities/Handler.php index 907e6a9..1883ec3 100644 --- a/ChainOfResponsibilities/Handler.php +++ b/ChainOfResponsibilities/Handler.php @@ -1,9 +1,5 @@ _data = $data; @@ -34,11 +35,11 @@ class SlowStorage extends Handler if ('get' === $req->verb) { if (array_key_exists($req->key, $this->_data)) { $req->response = $this->_data[$req->key]; + return true; } } return false; } - } diff --git a/Command/Invoker.php b/Command/Invoker.php index f3013e6..6f857ec 100644 --- a/Command/Invoker.php +++ b/Command/Invoker.php @@ -1,9 +1,5 @@ mediator; } + /** + * @param MediatorInterface $medium + */ public function __construct(MediatorInterface $medium) { // in this way, we are sure the concrete colleague knows the mediator $this->mediator = $medium; } - -} \ No newline at end of file +} diff --git a/Mediator/Mediator.php b/Mediator/Mediator.php index 98b34a1..7de6669 100644 --- a/Mediator/Mediator.php +++ b/Mediator/Mediator.php @@ -1,9 +1,5 @@ getMediator()->queryDb(); $this->getMediator()->sendResponse("Hello $data"); } - -} \ No newline at end of file +} diff --git a/State/OrderFactory.php b/State/OrderFactory.php index 55c7d80..0e61758 100644 --- a/State/OrderFactory.php +++ b/State/OrderFactory.php @@ -32,4 +32,4 @@ class OrderFactory break; } } -} \ No newline at end of file +} diff --git a/Tests/AbstractFactory/AbstractFactoryTest.php b/Tests/AbstractFactory/AbstractFactoryTest.php index 0ee562a..581c068 100644 --- a/Tests/AbstractFactory/AbstractFactoryTest.php +++ b/Tests/AbstractFactory/AbstractFactoryTest.php @@ -41,4 +41,4 @@ class AbstractFactoryTest extends \PHPUnit_Framework_TestCase * a given Abstract Factory */ } -} \ No newline at end of file +} diff --git a/Tests/Adapter/AdapterTest.php b/Tests/Adapter/AdapterTest.php index 7473de6..370a6c3 100644 --- a/Tests/Adapter/AdapterTest.php +++ b/Tests/Adapter/AdapterTest.php @@ -1,9 +1,5 @@ open(); $book->turnPage(); } - -} \ No newline at end of file +} diff --git a/Tests/Builder/DirectorTest.php b/Tests/Builder/DirectorTest.php index 83e2234..3d3e2cf 100644 --- a/Tests/Builder/DirectorTest.php +++ b/Tests/Builder/DirectorTest.php @@ -1,9 +1,5 @@ director->build($builder); $this->assertInstanceOf('DesignPatterns\Builder\Parts\Vehicle', $newVehicle); } - -} \ No newline at end of file +} diff --git a/Tests/ChainOfResponsibilities/ChainTest.php b/Tests/ChainOfResponsibilities/ChainTest.php index 337559b..e4ab54c 100644 --- a/Tests/ChainOfResponsibilities/ChainTest.php +++ b/Tests/ChainOfResponsibilities/ChainTest.php @@ -1,9 +1,5 @@ assertEquals('DesignPatterns\ChainOfResponsibilities\Responsible\SlowStorage', $request->forDebugOnly); } - -} \ No newline at end of file +} diff --git a/Tests/Command/CommandTest.php b/Tests/Command/CommandTest.php index 0df7f9e..7400139 100644 --- a/Tests/Command/CommandTest.php +++ b/Tests/Command/CommandTest.php @@ -1,9 +1,5 @@ expectOutputString('Hello World'); $this->invoker->run(); } - -} \ No newline at end of file +} diff --git a/Tests/Composite/FormTest.php b/Tests/Composite/FormTest.php index 41cf904..8a2aae3 100644 --- a/Tests/Composite/FormTest.php +++ b/Tests/Composite/FormTest.php @@ -1,9 +1,5 @@ assertTrue(is_subclass_of('DesignPatterns\Composite\Form', 'DesignPatterns\Composite\FormElement')); } - -} \ No newline at end of file +} diff --git a/Tests/DataMapper/UserMapperTest.php b/Tests/DataMapper/UserMapperTest.php index 2bce7b6..bd2d1c1 100644 --- a/Tests/DataMapper/UserMapperTest.php +++ b/Tests/DataMapper/UserMapperTest.php @@ -1,9 +1,5 @@ mapper->findById(404); } - } diff --git a/Tests/Decorator/DecoratorTest.php b/Tests/Decorator/DecoratorTest.php index 7f20bb6..c6202dd 100644 --- a/Tests/Decorator/DecoratorTest.php +++ b/Tests/Decorator/DecoratorTest.php @@ -1,9 +1,5 @@ getMockForAbstractClass('DesignPatterns\Decorator\Decorator', array($mock)); $this->assertNotNull($dec); } - -} \ No newline at end of file +} diff --git a/Tests/Facade/FacadeTest.php b/Tests/Facade/FacadeTest.php index 868ed32..0d91521 100644 --- a/Tests/Facade/FacadeTest.php +++ b/Tests/Facade/FacadeTest.php @@ -1,9 +1,5 @@ assertEquals('Linux', $os->getName()); } - -} \ No newline at end of file +} diff --git a/Tests/FactoryMethod/FactoryMethodTest.php b/Tests/FactoryMethod/FactoryMethodTest.php index 463c1c8..0796a98 100644 --- a/Tests/FactoryMethod/FactoryMethodTest.php +++ b/Tests/FactoryMethod/FactoryMethodTest.php @@ -1,9 +1,5 @@ type as $oneType) { $vehicle = $shop->create($oneType); - $this->assertInstanceOf('DesignPatterns\FactoryMethod\Vehicle', $vehicle); + $this->assertInstanceOf('DesignPatterns\FactoryMethod\VehicleInterface', $vehicle); } } @@ -51,5 +47,4 @@ class FactoryMethodTest extends \PHPUnit_Framework_TestCase { $shop->create('spaceship'); } - -} \ No newline at end of file +} diff --git a/Tests/FluentInterface/FluentInterfaceTest.php b/Tests/FluentInterface/FluentInterfaceTest.php index 7dec8d8..63be030 100644 --- a/Tests/FluentInterface/FluentInterfaceTest.php +++ b/Tests/FluentInterface/FluentInterfaceTest.php @@ -1,9 +1,5 @@ assertEquals('SELECT foo,bar FROM foobar AS f WHERE f.bar = ?', $query); } - -} \ No newline at end of file +} diff --git a/Tests/Iterator/IteratorTest.php b/Tests/Iterator/IteratorTest.php index de2e2b2..eab5a30 100644 --- a/Tests/Iterator/IteratorTest.php +++ b/Tests/Iterator/IteratorTest.php @@ -1,9 +1,5 @@ append(new \ArrayIterator($joker)); $this->assertCount(33, $newDeck); } - -} \ No newline at end of file +} diff --git a/Tests/Mediator/MediatorTest.php b/Tests/Mediator/MediatorTest.php index f4f689d..77db09f 100644 --- a/Tests/Mediator/MediatorTest.php +++ b/Tests/Mediator/MediatorTest.php @@ -1,9 +1,5 @@ expectOutputString('We are in DesignPatterns\NullObject\Service::doSomething'); $service->doSomething(); } - -} \ No newline at end of file +} diff --git a/Tests/SimpleFactory/SimpleFactoryTest.php b/Tests/SimpleFactory/SimpleFactoryTest.php index 42de427..48c949c 100644 --- a/Tests/SimpleFactory/SimpleFactoryTest.php +++ b/Tests/SimpleFactory/SimpleFactoryTest.php @@ -1,9 +1,5 @@ getMethod('__construct'); $this->assertTrue($meth->isPrivate()); } - -} \ No newline at end of file +} diff --git a/Tests/StaticFactory/StaticFactoryTest.php b/Tests/StaticFactory/StaticFactoryTest.php index 65087f5..d85f266 100644 --- a/Tests/StaticFactory/StaticFactoryTest.php +++ b/Tests/StaticFactory/StaticFactoryTest.php @@ -27,5 +27,4 @@ class StaticFactoryTest extends \PHPUnit_Framework_TestCase $obj = StaticFactory::factory($type); $this->assertInstanceOf('DesignPatterns\StaticFactory\FormatterInterface', $obj); } - } diff --git a/Tests/TemplateMethod/JourneyTest.php b/Tests/TemplateMethod/JourneyTest.php index bc87062..f592363 100644 --- a/Tests/TemplateMethod/JourneyTest.php +++ b/Tests/TemplateMethod/JourneyTest.php @@ -1,9 +1,5 @@ Date: Fri, 13 Sep 2013 14:30:24 +0200 Subject: [PATCH 23/28] cs --- AbstractFactory/MediaInterface.php | 2 +- Builder/CarBuilder.php | 19 ++++++++++++++++++- Builder/Parts/Wheel.php | 7 +++++-- ChainOfResponsibilities/Handler.php | 16 ++++++++++++---- .../Responsible/FastStorage.php | 18 +++++++++++++----- .../Responsible/SlowStorage.php | 8 ++++---- 6 files changed, 53 insertions(+), 17 deletions(-) diff --git a/AbstractFactory/MediaInterface.php b/AbstractFactory/MediaInterface.php index 16c5d78..92d0089 100644 --- a/AbstractFactory/MediaInterface.php +++ b/AbstractFactory/MediaInterface.php @@ -16,5 +16,5 @@ interface MediaInterface * * @return string */ - function render(); + public function render(); } diff --git a/Builder/CarBuilder.php b/Builder/CarBuilder.php index 515f00b..ce0e3f4 100644 --- a/Builder/CarBuilder.php +++ b/Builder/CarBuilder.php @@ -7,20 +7,31 @@ namespace DesignPatterns\Builder; */ class CarBuilder implements Builder { - + /** + * @var Parts\Car + */ protected $car; + /** + * @return void + */ public function addDoors() { $this->car->setPart('rightdoor', new Parts\Door()); $this->car->setPart('leftDoor', new Parts\Door()); } + /** + * @return void + */ public function addEngine() { $this->car->setPart('engine', new Parts\Engine()); } + /** + * @return void + */ public function addWheel() { $this->car->setPart('wheelLF', new Parts\Wheel()); @@ -29,11 +40,17 @@ class CarBuilder implements Builder $this->car->setPart('wheelRR', new Parts\Wheel()); } + /** + * @return void + */ public function createVehicle() { $this->car = new Parts\Car(); } + /** + * @return Parts\Car + */ public function getVehicle() { return $this->car; diff --git a/Builder/Parts/Wheel.php b/Builder/Parts/Wheel.php index d2b8950..71337e4 100644 --- a/Builder/Parts/Wheel.php +++ b/Builder/Parts/Wheel.php @@ -2,7 +2,10 @@ namespace DesignPatterns\Builder\Parts; +/** + * Class Wheel + */ class Wheel { - -} \ No newline at end of file + +} diff --git a/ChainOfResponsibilities/Handler.php b/ChainOfResponsibilities/Handler.php index 1883ec3..35ec769 100644 --- a/ChainOfResponsibilities/Handler.php +++ b/ChainOfResponsibilities/Handler.php @@ -13,7 +13,7 @@ namespace DesignPatterns\ChainOfResponsibilities; abstract class Handler { /** - * @var null + * @var Handler */ private $successor = null; @@ -22,14 +22,16 @@ abstract class Handler * * A prepend method could be done with the same spirit * - * You could also send the successor in the contructor but in PHP it is a + * You could also send the successor in the constructor but in PHP it is a * bad idea because you have to remove the type-hint of the parameter because * the last handler has a null successor. * - * And if you override the contructor, that Handler can no longer have a + * And if you override the constructor, that Handler can no longer have a * successor. One solution is to provide a NullObject (see pattern). * It is more preferable to keep the constructor "free" to inject services * you need with the DiC of symfony2 for example. + * + * @param Handler $handler */ final public function append(Handler $handler) { @@ -46,6 +48,10 @@ abstract class Handler * This approach by using a template method pattern ensures you that * each subclass will not forget to call the successor. Beside, the returned * boolean value indicates you if the request have been processed or not. + * + * @param Request $req + * + * @return bool */ final public function handle(Request $req) { @@ -63,7 +69,9 @@ abstract class Handler /** * Each concrete handler has to implement the processing of the request - * + * + * @param Request $req + * * @return bool true if the request has been processed */ abstract protected function processing(Request $req); diff --git a/ChainOfResponsibilities/Responsible/FastStorage.php b/ChainOfResponsibilities/Responsible/FastStorage.php index ccdf518..d02fb5a 100644 --- a/ChainOfResponsibilities/Responsible/FastStorage.php +++ b/ChainOfResponsibilities/Responsible/FastStorage.php @@ -5,22 +5,30 @@ namespace DesignPatterns\ChainOfResponsibilities\Responsible; use DesignPatterns\ChainOfResponsibilities\Handler; use DesignPatterns\ChainOfResponsibilities\Request; +/** + * Class FastStorage + */ class FastStorage extends Handler { + /** + * @var array + */ + protected $data = array(); - protected $_data = array(); - + /** + * @param array $data + */ public function __construct($data = array()) { - $this->_data = $data; + $this->data = $data; } protected function processing(Request $req) { if ('get' === $req->verb) { - if (array_key_exists($req->key, $this->_data)) { + if (array_key_exists($req->key, $this->data)) { // the handler IS responsible and then processes the request - $req->response = $this->_data[$req->key]; + $req->response = $this->data[$req->key]; // instead of returning true, I could return the value but it proves // to be a bad idea. What if the value IS "false" ? return true; diff --git a/ChainOfResponsibilities/Responsible/SlowStorage.php b/ChainOfResponsibilities/Responsible/SlowStorage.php index 9b835d4..8d64484 100644 --- a/ChainOfResponsibilities/Responsible/SlowStorage.php +++ b/ChainOfResponsibilities/Responsible/SlowStorage.php @@ -20,21 +20,21 @@ class SlowStorage extends Handler /** * @var array */ - protected $_data = array(); + protected $data = array(); /** * @param array $data */ public function __construct($data = array()) { - $this->_data = $data; + $this->data = $data; } protected function processing(Request $req) { if ('get' === $req->verb) { - if (array_key_exists($req->key, $this->_data)) { - $req->response = $this->_data[$req->key]; + if (array_key_exists($req->key, $this->data)) { + $req->response = $this->data[$req->key]; return true; } From 69aa0ae5b52dd51ba0b85e5fb09fb49bf4b64195 Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Fri, 13 Sep 2013 14:34:13 +0200 Subject: [PATCH 24/28] cs Prototype --- Prototype/BarBookPrototype.php | 22 ++++++++++++ Prototype/BookPrototype.php | 48 +++++++++++++++++++++++++ Prototype/FooBookPrototype.php | 19 ++++++++++ Prototype/Prototype.php | 65 ---------------------------------- Prototype/index.php | 12 +++++++ 5 files changed, 101 insertions(+), 65 deletions(-) create mode 100644 Prototype/BarBookPrototype.php create mode 100644 Prototype/BookPrototype.php create mode 100644 Prototype/FooBookPrototype.php delete mode 100644 Prototype/Prototype.php create mode 100644 Prototype/index.php diff --git a/Prototype/BarBookPrototype.php b/Prototype/BarBookPrototype.php new file mode 100644 index 0000000..c254496 --- /dev/null +++ b/Prototype/BarBookPrototype.php @@ -0,0 +1,22 @@ +title; + } + + /** + * @param string $title + */ + public function setTitle($title) + { + $this->title = $title; + } +} diff --git a/Prototype/FooBookPrototype.php b/Prototype/FooBookPrototype.php new file mode 100644 index 0000000..ed2f250 --- /dev/null +++ b/Prototype/FooBookPrototype.php @@ -0,0 +1,19 @@ +_title; - } - - public function setTitle($title) - { - $this->_title = $title; - } -} - -class FooBookPrototype extends BookPrototype -{ - protected $_category = 'Foo'; - - public function __clone() - { - - } -} - -class BarBookPrototype extends BookPrototype -{ - protected $_category = 'Bar'; - - - public function __clone() - { - - } -} - -$fooPrototype = new FooBookPrototype(); -$barPrototype = new BarBookPrototype(); - -// now lets say we need 10,000 books of foo and 5,000 of bar ... -for ($i = 0; $i < 10000; $i++) { - $book = clone $fooPrototype; - $book->setTitle('Foo Book No ' . $i); -} diff --git a/Prototype/index.php b/Prototype/index.php new file mode 100644 index 0000000..70e2ac1 --- /dev/null +++ b/Prototype/index.php @@ -0,0 +1,12 @@ +setTitle('Foo Book No ' . $i); +} From 4b6641750974b2bc1ffde6886da24683e0ac40d4 Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Fri, 13 Sep 2013 14:36:29 +0200 Subject: [PATCH 25/28] cs Mediator --- Mediator/Mediator.php | 21 +++++++++++++++++++-- Mediator/MediatorInterface.php | 6 +++--- Mediator/Subsystem/Client.php | 10 ++++++++-- Mediator/Subsystem/Database.php | 5 +++-- Mediator/Subsystem/Server.php | 4 +++- 5 files changed, 36 insertions(+), 10 deletions(-) diff --git a/Mediator/Mediator.php b/Mediator/Mediator.php index 7de6669..9a9c3f1 100644 --- a/Mediator/Mediator.php +++ b/Mediator/Mediator.php @@ -25,6 +25,11 @@ class Mediator implements MediatorInterface protected $database; protected $client; + /** + * @param Subsystem\Database $db + * @param Subsystem\Client $cl + * @param Subsystem\Server $srv + */ public function setColleague(Subsystem\Database $db, Subsystem\Client $cl, Subsystem\Server $srv) { $this->database = $db; @@ -32,19 +37,31 @@ class Mediator implements MediatorInterface $this->client = $cl; } + /** + * make request + */ public function makeRequest() { $this->server->process(); } + /** + * query db + * + * @return mixed + */ public function queryDb() { return $this->database->getData(); } + /** + * send response + * + * @param string $content + */ public function sendResponse($content) { $this->client->output($content); } - -} \ No newline at end of file +} diff --git a/Mediator/MediatorInterface.php b/Mediator/MediatorInterface.php index 15ea67b..d7e6a41 100644 --- a/Mediator/MediatorInterface.php +++ b/Mediator/MediatorInterface.php @@ -13,15 +13,15 @@ interface MediatorInterface * * @param string $content */ - function sendResponse($content); + public function sendResponse($content); /** * makes a request */ - function makeRequest(); + public function makeRequest(); /** * queries the DB */ - function queryDb(); + public function queryDb(); } diff --git a/Mediator/Subsystem/Client.php b/Mediator/Subsystem/Client.php index 899575d..ef00aa0 100644 --- a/Mediator/Subsystem/Client.php +++ b/Mediator/Subsystem/Client.php @@ -9,15 +9,21 @@ use DesignPatterns\Mediator\Colleague; */ class Client extends Colleague { - + /** + * request + */ public function request() { $this->getMediator()->makeRequest(); } + /** + * output content + * + * @param string $content + */ public function output($content) { echo $content; } - } diff --git a/Mediator/Subsystem/Database.php b/Mediator/Subsystem/Database.php index 92c4f17..80acf28 100644 --- a/Mediator/Subsystem/Database.php +++ b/Mediator/Subsystem/Database.php @@ -9,10 +9,11 @@ use DesignPatterns\Mediator\Colleague; */ class Database extends Colleague { - + /** + * @return string + */ public function getData() { return "World"; } - } diff --git a/Mediator/Subsystem/Server.php b/Mediator/Subsystem/Server.php index f23414f..34b7400 100644 --- a/Mediator/Subsystem/Server.php +++ b/Mediator/Subsystem/Server.php @@ -9,7 +9,9 @@ use DesignPatterns\Mediator\Colleague; */ class Server extends Colleague { - + /** + * process on server + */ public function process() { $data = $this->getMediator()->queryDb(); From 9484868299bf5743fef0168d552fafb40825e1fc Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Sat, 21 Sep 2013 22:17:54 +0200 Subject: [PATCH 26/28] cs Iterator and Registry --- Iterator/CardGame.php | 87 -------------------------- Iterator/File.php | 51 +++++++++++++++ Iterator/Row.php | 27 ++++++++ Iterator/{Iterator.php => RowSet.php} | 89 ++++++++------------------- Multiton/Multiton.php | 9 +-- Registry/Registry.php | 6 -- Registry/index.php | 9 +++ 7 files changed, 118 insertions(+), 160 deletions(-) delete mode 100644 Iterator/CardGame.php create mode 100644 Iterator/File.php create mode 100644 Iterator/Row.php rename Iterator/{Iterator.php => RowSet.php} (56%) create mode 100644 Registry/index.php diff --git a/Iterator/CardGame.php b/Iterator/CardGame.php deleted file mode 100644 index 4d5997a..0000000 --- a/Iterator/CardGame.php +++ /dev/null @@ -1,87 +0,0 @@ -number) . ' of ' . current($this->color); - } - - /** - * Return the current key - * - * @return string - */ - public function key() - { - return current($this->color) . current($this->number); - } - - /** - * Go to the next item in the collection - */ - public function next() - { - if (false === next($this->number)) { - if (false !== next($this->color)) { - reset($this->number); - } - } - } - - /** - * Go to the first item in the collection - */ - public function rewind() - { - reset($this->color); - reset($this->number); - } - - /** - * Is the current position a valid item (true) - * or do we reach the end (false) ? - * - * @return boolean - */ - public function valid() - { - return current($this->number) || current($this->color); - } -} diff --git a/Iterator/File.php b/Iterator/File.php new file mode 100644 index 0000000..0e1aa3d --- /dev/null +++ b/Iterator/File.php @@ -0,0 +1,51 @@ +rowSet = new Rowset($this); + } + + /** + * processes the rowSet + */ + public function process() + { + // this is the place to show how using an iterator, with foreach + // See the CardGame.php file + $this->rowSet->process(); + } +} diff --git a/Iterator/Row.php b/Iterator/Row.php new file mode 100644 index 0000000..df4002d --- /dev/null +++ b/Iterator/Row.php @@ -0,0 +1,27 @@ +data = $data; + } + + /** + * {@inheritdoc} + */ + public function process() + { + // do some fancy things here ... + } +} diff --git a/Iterator/Iterator.php b/Iterator/RowSet.php similarity index 56% rename from Iterator/Iterator.php rename to Iterator/RowSet.php index d05fcc6..f1ef5d7 100644 --- a/Iterator/Iterator.php +++ b/Iterator/RowSet.php @@ -1,53 +1,11 @@ rowSet = new Rowset($this); - } - - public function process() - { - // this is the place to show how using an iterator, with foreach - // See the CardGame.php file - $this->rowSet->process(); - } -} - -class Rowset implements \Iterator +class RowSet implements \Iterator { /** * @var @@ -59,6 +17,11 @@ class Rowset implements \Iterator */ protected $file; + /** + * @var int + */ + protected $lineNumber; + /** * @param string $file */ @@ -79,20 +42,26 @@ class Rowset implements \Iterator * THE key feature of the Iterator Pattern is to provide a *public contract* * to iterate on a collection without knowing how items are handled inside * the collection. It is not just an easy way to use "foreach" - * + * * One cannot see the point of iterator pattern if you iterate on $this. - * This example is unclear and mixed with some Composite pattern ideas. + * This example is unclear and mixed with some Composite pattern ideas. */ foreach ($this as $line => $row) { $row->process(); } } + /** + * {@inheritdoc} + */ public function rewind() { // seek to first line from $this->file } + /** + * {@inheritdoc} + */ public function next() { // read the next line from $this->file @@ -104,34 +73,28 @@ class Rowset implements \Iterator } } + /** + * {@inheritdoc} + */ public function current() { return $this->currentRow; } + /** + * {@inheritdoc} + */ public function valid() { return null !== $this->currentRow; } + /** + * {@inheritdoc} + */ public function key() { // you would want to increment this in next() or whatsoever - return $this->_lineNumber; - } -} - -class Row -{ - protected $_data; - - public function __construct($data) - { - $this->_data = $data; - } - - public function process() - { - // do some fancy things here ... + return $this->lineNumber; } } diff --git a/Multiton/Multiton.php b/Multiton/Multiton.php index 74f9dcd..1dddebb 100644 --- a/Multiton/Multiton.php +++ b/Multiton/Multiton.php @@ -37,7 +37,7 @@ class Multiton * * @var array */ - private static $_instances = array(); + private static $instances = array(); /** * should not be called from outside: private! @@ -53,15 +53,16 @@ class Multiton * uses lazy initialization * * @param string $instanceName + * * @return Multiton */ public static function getInstance($instanceName) { - if ( ! array_key_exists($instanceName, self::$_instances)) { - self::$_instances[$instanceName] = new self(); + if (!array_key_exists($instanceName, self::$instances)) { + self::$instances[$instanceName] = new self(); } - return self::$_instances[$instanceName]; + return self::$instances[$instanceName]; } /** diff --git a/Registry/Registry.php b/Registry/Registry.php index 65509c0..020398a 100644 --- a/Registry/Registry.php +++ b/Registry/Registry.php @@ -52,9 +52,3 @@ abstract class Registry // typically there would be methods to check if a key has already been registered and so on ... } - -// while bootstrapping the application -Registry::set(Registry::LOGGER, new \StdClass()); - -// throughout the application -Registry::get(Registry::LOGGER)->log('foo'); diff --git a/Registry/index.php b/Registry/index.php new file mode 100644 index 0000000..0a20047 --- /dev/null +++ b/Registry/index.php @@ -0,0 +1,9 @@ +log('foo'); From f6651bafaaddf3b6c0b770c76208d3287f1e9d8c Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Sat, 21 Sep 2013 22:25:20 +0200 Subject: [PATCH 27/28] cs --- Adapter/EBookInterface.php | 16 +++- Builder/BikeBuilder.php | 26 ++++- Builder/{Builder.php => BuilderInterface.php} | 2 +- Builder/CarBuilder.php | 2 +- Builder/Director.php | 9 +- .../ChainOfResponsibilities.php | 96 ------------------- ChainOfResponsibilities/README.md | 13 +++ Tests/Builder/DirectorTest.php | 2 +- Tests/Iterator/IteratorTest.php | 63 ------------ 9 files changed, 56 insertions(+), 173 deletions(-) rename Builder/{Builder.php => BuilderInterface.php} (96%) delete mode 100644 ChainOfResponsibilities/ChainOfResponsibilities.php create mode 100644 ChainOfResponsibilities/README.md delete mode 100644 Tests/Iterator/IteratorTest.php diff --git a/Adapter/EBookInterface.php b/Adapter/EBookInterface.php index c569ab6..86eed82 100644 --- a/Adapter/EBookInterface.php +++ b/Adapter/EBookInterface.php @@ -7,7 +7,17 @@ namespace DesignPatterns\Adapter; */ interface EBookInterface { - function pressNext(); + /** + * go to next page + * + * @return mixed + */ + public function pressNext(); - function pressStart(); -} \ No newline at end of file + /** + * start the book + * + * @return mixed + */ + public function pressStart(); +} diff --git a/Builder/BikeBuilder.php b/Builder/BikeBuilder.php index ee47ca1..a6f1a30 100644 --- a/Builder/BikeBuilder.php +++ b/Builder/BikeBuilder.php @@ -5,35 +5,51 @@ namespace DesignPatterns\Builder; /** * BikeBuilder builds bike */ -class BikeBuilder implements Builder +class BikeBuilder implements BuilderInterface { - + /** + * @var Parts\Bike + */ protected $bike; + /** + * {@inheritdoc} + */ public function addDoors() { - + } + /** + * {@inheritdoc} + */ public function addEngine() { $this->bike->setPart('engine', new Parts\Engine()); } + /** + * {@inheritdoc} + */ public function addWheel() { $this->bike->setPart('forwardWheel', new Parts\Wheel()); $this->bike->setPart('rearWheel', new Parts\Wheel()); } + /** + * {@inheritdoc} + */ public function createVehicle() { $this->bike = new Parts\Bike(); } + /** + * {@inheritdoc} + */ public function getVehicle() { return $this->bike; } - -} \ No newline at end of file +} diff --git a/Builder/Builder.php b/Builder/BuilderInterface.php similarity index 96% rename from Builder/Builder.php rename to Builder/BuilderInterface.php index d165ec4..f52b56f 100644 --- a/Builder/Builder.php +++ b/Builder/BuilderInterface.php @@ -14,7 +14,7 @@ namespace DesignPatterns\Builder; * Note: Builders have often a fluent interface, see the mock builder of * PHPUnit for example. */ -interface Builder +interface BuilderInterface { /** * @return mixed diff --git a/Builder/CarBuilder.php b/Builder/CarBuilder.php index ce0e3f4..b89ee20 100644 --- a/Builder/CarBuilder.php +++ b/Builder/CarBuilder.php @@ -5,7 +5,7 @@ namespace DesignPatterns\Builder; /** * CarBuilder builds car */ -class CarBuilder implements Builder +class CarBuilder implements BuilderInterface { /** * @var Parts\Car diff --git a/Builder/Director.php b/Builder/Director.php index 32ffaa7..6a04fad 100644 --- a/Builder/Director.php +++ b/Builder/Director.php @@ -14,8 +14,12 @@ class Director /** * The director don't know 'bout concrete part + * + * @param BuilderInterface $builder + * + * @return Parts\Vehicle */ - public function build(Builder $builder) + public function build(BuilderInterface $builder) { $builder->createVehicle(); $builder->addDoors(); @@ -24,5 +28,4 @@ class Director return $builder->getVehicle(); } - -} \ No newline at end of file +} diff --git a/ChainOfResponsibilities/ChainOfResponsibilities.php b/ChainOfResponsibilities/ChainOfResponsibilities.php deleted file mode 100644 index 257f7c9..0000000 --- a/ChainOfResponsibilities/ChainOfResponsibilities.php +++ /dev/null @@ -1,96 +0,0 @@ -_data = $data; - } - - /** - * this class has no next handler, so it MUST be able to handle all requests - * - * @param $key - * @return mixed - */ - public function get($key) - { - return $this->_data[$key]; - } -} - -class FastStorage implements KeyValueStorage -{ - /** - * @var array - */ - protected $_data; - - /** - * the next handler in the chain - * - * @var \DesignPatterns\KeyValueStorage - */ - protected $_nextHandler; - - public function __construct(array $data, KeyValueStorage $nextHandler) - { - $this->_data = $data; - $this->_nextHandler = $nextHandler; - } - - /** - * when this storage gets a "miss", search in next handler - * - * @param $key - * @return mixed - */ - public function get($key) - { - if (true /* miss */) { - // delegate the call to the next handler in the chain - return $this->_nextHandler->get($key); - } - } -} - -// BUILD THE STORAGES AND CHAIN - -$slowStorage = new SlowStorage(array('foo' => 'bar')); -$fastStorage = new FastStorage(array('bar' => 'baz'), $slowStorage); - -$fastStorage->get('foo'); // will be handled by SlowStorage -$fastStorage->get('bar'); // will be handled by FastStorage - -/** - * In this example we could also add a abstract class and extend it to build Fast- and SlowStorage. That class would - * then manage the chain and when the cache hits a "miss", it would check if there is a next handler - */ diff --git a/ChainOfResponsibilities/README.md b/ChainOfResponsibilities/README.md new file mode 100644 index 0000000..44496bf --- /dev/null +++ b/ChainOfResponsibilities/README.md @@ -0,0 +1,13 @@ +# chain of responsibilities + +## Purpose: + +To build a chain of objects to handle a call. if one object cannot handle a call, it delegates the call to the next +in the chain and so forth + +## Examples: + +* logging framework +* spam filter + Caching: first object is an instance of e.g. a Memcached Interface, if that "misses" it delegates the call to the database interface +* Yii Framework: CFilterChain is a chain of controller action filters. the executing point is passed from one filter to the next along the chain, and only if all filters say "yes", the action can be invoked at last. \ No newline at end of file diff --git a/Tests/Builder/DirectorTest.php b/Tests/Builder/DirectorTest.php index 3d3e2cf..381cb0f 100644 --- a/Tests/Builder/DirectorTest.php +++ b/Tests/Builder/DirectorTest.php @@ -33,7 +33,7 @@ class DirectorTest extends \PHPUnit_Framework_TestCase * * @dataProvider getBuilder */ - public function testBuild(\DesignPatterns\Builder\Builder $builder) + public function testBuild(\DesignPatterns\Builder\BuilderInterface $builder) { $newVehicle = $this->director->build($builder); $this->assertInstanceOf('DesignPatterns\Builder\Parts\Vehicle', $newVehicle); diff --git a/Tests/Iterator/IteratorTest.php b/Tests/Iterator/IteratorTest.php deleted file mode 100644 index eab5a30..0000000 --- a/Tests/Iterator/IteratorTest.php +++ /dev/null @@ -1,63 +0,0 @@ -deck = new CardGame(); - } - - /** - * This is the client of the iterator. - * It remains unchanged even if one day I decide to use MongoDB to store the - * card. - */ - public function testCardinal() - { - $counter = 0; - foreach ($this->deck as $key => $card) { - $counter++; - } - - $this->assertEquals(32, $counter); - } - - /** - * Some fancy functions of PHP. - */ - public function testExampleOf_PHP_Helper() - { - // PHPUnit works on array or iterator : - $this->assertCount(32, $this->deck); - // a easy way to get an array from interator : - $cards = iterator_to_array($this->deck); - $this->assertEquals('A of S', $cards['SA']); - // a easy way to get an iterator from an array : - $iterator = new \ArrayIterator($cards); - $this->assertInstanceOf('\Iterator', $iterator); - } - - /** - * Iterator can be combine, chained, filter, there are many in the SPL - * and sadly they are rarely used. - */ - public function testIteratorCombining() - { - // a fancy way to add a joker to the deck : - $joker = array('JK' => 'Joker'); - $newDeck = new \AppendIterator(); - $newDeck->append($this->deck); - $newDeck->append(new \ArrayIterator($joker)); - $this->assertCount(33, $newDeck); - } -} From 8ec5e0de147535deb663a5aaea3429608abb0dd3 Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Sat, 21 Sep 2013 22:28:09 +0200 Subject: [PATCH 28/28] added hint to coding standard in README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index bb90373..09d628a 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ The patterns can be structured in roughly three different categories. Please cli ## Contribute Please feel free to fork and extend existing or add your own examples and send a pull request with your changes! +To establish a consistent code quality, please check your code using [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) against [this standard](https://github.com/domnikl/Symfony2-coding-standard). ## License