From 97096bc23fcb2506e58b38df5c1cb5bf13ddc681 Mon Sep 17 00:00:00 2001 From: Trismegiste Date: Sat, 11 May 2013 02:06:15 +0200 Subject: [PATCH 1/4] fixing the inheritance tree for decorator --- Decorator/Decorator.php | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/Decorator/Decorator.php b/Decorator/Decorator.php index 856b181..67c5b35 100644 --- a/Decorator/Decorator.php +++ b/Decorator/Decorator.php @@ -35,17 +35,28 @@ class Webservice implements Renderer } } -abstract class Decorator +/** + * the Deoorator MUST implement the Renderer 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 { protected $_wrapped; - public function __construct($wrappable) + /** + * You must type-hint the wrapped component : + * It ensures you can call renderData() in the subclasses ! + * + * @param Renderer $wrappable + */ + public function __construct(Renderer $wrappable) { $this->_wrapped = $wrappable; } } -class RenderInJson extends Decorator implements Renderer +class RenderInJson extends Decorator { public function renderData() { @@ -54,7 +65,7 @@ class RenderInJson extends Decorator implements Renderer } } -class RenderInXml extends Decorator implements Renderer +class RenderInXml extends Decorator { public function renderData() { From cfa901490681247b01da5913b0f3f1910916a449 Mon Sep 17 00:00:00 2001 From: Trismegiste Date: Sat, 11 May 2013 02:07:29 +0200 Subject: [PATCH 2/4] fixing namespace --- Decorator/Decorator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Decorator/Decorator.php b/Decorator/Decorator.php index 67c5b35..727c4c9 100644 --- a/Decorator/Decorator.php +++ b/Decorator/Decorator.php @@ -1,6 +1,6 @@ Date: Sat, 11 May 2013 02:50:05 +0200 Subject: [PATCH 3/4] fix PSR-0 --- Decorator/Decorator.php | 46 -------------------------------------- Decorator/RenderInJson.php | 12 ++++++++++ Decorator/RenderInXml.php | 18 +++++++++++++++ Decorator/Renderer.php | 8 +++++++ Decorator/Webservice.php | 18 +++++++++++++++ 5 files changed, 56 insertions(+), 46 deletions(-) create mode 100644 Decorator/RenderInJson.php create mode 100644 Decorator/RenderInXml.php create mode 100644 Decorator/Renderer.php create mode 100644 Decorator/Webservice.php diff --git a/Decorator/Decorator.php b/Decorator/Decorator.php index 727c4c9..3231f09 100644 --- a/Decorator/Decorator.php +++ b/Decorator/Decorator.php @@ -15,25 +15,6 @@ namespace DesignPatterns\Decorator; * */ -interface Renderer -{ - public function renderData(); -} - -class Webservice implements Renderer -{ - protected $_data; - - public function __construct($data) - { - $this->_data = $data; - } - - public function renderData() - { - return $this->_data; - } -} /** * the Deoorator MUST implement the Renderer contract, this is the key-feature @@ -56,30 +37,3 @@ abstract class Decorator implements Renderer } } -class RenderInJson extends Decorator -{ - public function renderData() - { - $output = $this->_wrapped->renderData(); - return json_encode($output); - } -} - -class RenderInXml extends Decorator -{ - public function renderData() - { - $output = $this->_wrapped->renderData(); - // do some fany conversion to xml from array ... - return simplexml_load_string($output); - } -} - -// Create a normal service -$service = new Webservice(array('foo' => 'bar')); - -// Wrap service with a JSON decorator for renderers -$service = new RenderInJson($service); -// Our Renderer will now output JSON instead of an array - -echo $service->renderData(); diff --git a/Decorator/RenderInJson.php b/Decorator/RenderInJson.php new file mode 100644 index 0000000..57f8b06 --- /dev/null +++ b/Decorator/RenderInJson.php @@ -0,0 +1,12 @@ +_wrapped->renderData(); + return json_encode($output); + } +} diff --git a/Decorator/RenderInXml.php b/Decorator/RenderInXml.php new file mode 100644 index 0000000..6e594f9 --- /dev/null +++ b/Decorator/RenderInXml.php @@ -0,0 +1,18 @@ +_wrapped->renderData(); + // do some fany 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 new file mode 100644 index 0000000..6a01d4e --- /dev/null +++ b/Decorator/Renderer.php @@ -0,0 +1,8 @@ +_data = $data; + } + + public function renderData() + { + return $this->_data; + } +} From 185baaae735666e2cbc0dff2e78f70ad53124996 Mon Sep 17 00:00:00 2001 From: Trismegiste Date: Sat, 11 May 2013 02:50:22 +0200 Subject: [PATCH 4/4] test decorator --- Tests/Decorator/DecoratorTest.php | 40 +++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 Tests/Decorator/DecoratorTest.php diff --git a/Tests/Decorator/DecoratorTest.php b/Tests/Decorator/DecoratorTest.php new file mode 100644 index 0000000..f8a759b --- /dev/null +++ b/Tests/Decorator/DecoratorTest.php @@ -0,0 +1,40 @@ +service = new Decorator\Webservice(array('foo' => 'bar')); + } + + public function testJsonDecorator() + { + // Wrap service with a JSON decorator for renderers + $service = new Decorator\RenderInJson($this->service); + // Our Renderer will now output JSON instead of an array + $this->assertEquals('{"foo":"bar"}', $service->renderData()); + } + + public function testXmlDecorator() + { + // Wrap service with a JSON decorator for renderers + $service = new Decorator\RenderInXml($this->service); + // Our Renderer will now output XML instead of an array + $this->assertXmlStringEqualsXmlString('bar', $service->renderData()); + } + +} \ No newline at end of file