From 11d64bf50d01ba077d4eeb4fc9a14d40d8b9baf5 Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Fri, 26 Aug 2011 19:29:16 +0200 Subject: [PATCH 1/6] added Decorator pattern --- Decorator/Decorator.php | 84 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 Decorator/Decorator.php diff --git a/Decorator/Decorator.php b/Decorator/Decorator.php new file mode 100644 index 0000000..d1ea220 --- /dev/null +++ b/Decorator/Decorator.php @@ -0,0 +1,84 @@ +_data = $data; + } + + /** + * + * + * @param WebserviceDecorator $decorator + * @return void + */ + public function addDecorator(WebserviceDecorator $decorator) + { + $this->_decorators[] = $decorator; + } + + /** + * @return string + */ + public function renderData() + { + $response = ''; + foreach ($this->_decorators as $decorator) { + $response = $decorator->renderData($this->_data); + } + + return $response; + } +} + +interface WebserviceDecorator +{ + public function renderData($data); +} + +class JsonDecorator implements WebserviceDecorator +{ + public function renderData($data) + { + return json_encode($data); + } +} + +class XmlDecorator implements WebserviceDecorator +{ + public function renderData($data) + { + // do some fany conversion to xml from array ... + return simplexml_load_string($data); + } +} + +$service = new Webservice(array('foo' => 'bar')); +$service->addDecorator(new JsonDecorator()); +echo $service->renderData(); \ No newline at end of file From b9c8cd79c99a04baad231086d76b1aea81a1a993 Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Fri, 26 Aug 2011 19:43:54 +0200 Subject: [PATCH 2/6] added proxy pattern --- Proxy/Proxy.php | 94 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 Proxy/Proxy.php diff --git a/Proxy/Proxy.php b/Proxy/Proxy.php new file mode 100644 index 0000000..88f13d9 --- /dev/null +++ b/Proxy/Proxy.php @@ -0,0 +1,94 @@ +_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 $_isDirrty = 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->_isDirrty = true; + } + } + + /** + * magic setter + * + * @param string $name + * @param mixed $value + * @return void + */ + public function __set($name, $value) + { + $this->_isDirrty = true; + parent::__set($name, $value); + } +} From a13f4b86c8cfa5597c677f67332c9aee8104f86f Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Fri, 26 Aug 2011 20:01:14 +0200 Subject: [PATCH 3/6] added iterator pattern and basic sample --- Iterator/Iterator.php | 109 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 Iterator/Iterator.php diff --git a/Iterator/Iterator.php b/Iterator/Iterator.php new file mode 100644 index 0000000..d27adae --- /dev/null +++ b/Iterator/Iterator.php @@ -0,0 +1,109 @@ +_rowset = new Rowset($this); + } + + public function process() + { + $this->_rowset->process(); + } +} + +class Rowset implements Iterator +{ + protected $_currentRow; + + protected $_file; + + public function __construct($file) + { + $this->_file = $file; + } + + /** + * composite pattern: run through all rows and process them + * + * @return void + */ + public function process() + { + // this actually calls rewind(), { next(), valid(), key() and current() :} + foreach ($this as $line => $row) { + $row->process(); + } + } + + public function rewind() + { + // seek to first line from $this->_file + } + + public function next() + { + // read the next line from $this->_file + if (!$eof) { + $data = ''; // get the line + $this->_currentRow = new Row($data); + } else { + $this->_currentRow = null; + } + } + + public function current() + { + return $this->_currentRow; + } + + public function valid() + { + return null !== $this->_currentRow; + } + + 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 ... + } +} \ No newline at end of file From b0f84c319bb60d6d512ddc206bc329a3e4b9c82a Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Sat, 27 Aug 2011 10:05:15 +0200 Subject: [PATCH 4/6] added new example for Composite pattern --- Composite/Composite.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Composite/Composite.php b/Composite/Composite.php index 65aca01..4236d44 100644 --- a/Composite/Composite.php +++ b/Composite/Composite.php @@ -11,6 +11,7 @@ namespace DesignPatterns; * Example: * - a form class instance handles all its form elements like a single instance of the form, when render() is called, it * subsequently runs trough all its child elements and calls render() on them + * - Zend_Config: a tree of configuration options, each one is a Zend_Config object * */ class Form From 6208bed58a9265a4f189cf60c8471be3d052c58b Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Sat, 27 Aug 2011 10:05:33 +0200 Subject: [PATCH 5/6] added chain of responsibilities pattern --- .../ChainOfResponsibilities.php | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 ChainOfResponsibilities/ChainOfResponsibilities.php diff --git a/ChainOfResponsibilities/ChainOfResponsibilities.php b/ChainOfResponsibilities/ChainOfResponsibilities.php new file mode 100644 index 0000000..d8639fc --- /dev/null +++ b/ChainOfResponsibilities/ChainOfResponsibilities.php @@ -0,0 +1,90 @@ +_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 + */ \ No newline at end of file From b02590628118b847412c1fe4c9827a9091844aed Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Sat, 27 Aug 2011 10:34:12 +0200 Subject: [PATCH 6/6] added observer pattern --- Observer/Observer.php | 71 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 Observer/Observer.php diff --git a/Observer/Observer.php b/Observer/Observer.php new file mode 100644 index 0000000..5b7aacd --- /dev/null +++ b/Observer/Observer.php @@ -0,0 +1,71 @@ +_observers[] = $observer; + } + + /** + * detach an observer + * + * @param \SplObserver $observer + * @return void + */ + public function detach(\SplObserver $observer) + { + $index = array_search($observer, $this->_observers); + + if (false !== $index) { + unset($this->_observers[$index]); + } + } + + /** + * + * + * @return void + */ + public function notify() + { + /** @var SplObserver $observer */ + foreach ($this->_observers as $observer) { + $observer->update($this); + } + } +} \ No newline at end of file