From d779b1e86aae829101e3b2ed77672c7ff95b5df6 Mon Sep 17 00:00:00 2001 From: Jan Brecka Date: Mon, 24 Mar 2014 16:51:49 +0100 Subject: [PATCH 1/3] add object pool pattern --- Pool/Pool.php | 31 +++++++++++++++++++++++ Pool/Processor.php | 54 +++++++++++++++++++++++++++++++++++++++++ Pool/README.md | 9 +++++++ Pool/Worker.php | 22 +++++++++++++++++ Pool/index.php | 17 +++++++++++++ README.md | 1 + Tests/Pool/PoolTest.php | 32 ++++++++++++++++++++++++ 7 files changed, 166 insertions(+) create mode 100644 Pool/Pool.php create mode 100644 Pool/Processor.php create mode 100644 Pool/README.md create mode 100644 Pool/Worker.php create mode 100644 Pool/index.php create mode 100644 Tests/Pool/PoolTest.php diff --git a/Pool/Pool.php b/Pool/Pool.php new file mode 100644 index 0000000..a38da74 --- /dev/null +++ b/Pool/Pool.php @@ -0,0 +1,31 @@ +class = $class; + } + + public function get() + { + if (count($this->instances) > 0) { + return array_pop($this->instances); + } + + return new $this->class(); + } + + public function dispose($instance) + { + $this->instances[] = $instance; + } + +} + diff --git a/Pool/Processor.php b/Pool/Processor.php new file mode 100644 index 0000000..a3cac2d --- /dev/null +++ b/Pool/Processor.php @@ -0,0 +1,54 @@ +pool = $pool; + } + + public function process($image) + { + if ($this->processing++ < $this->maxProcesses) { + $this->createWorker($image); + } else { + $this->pushToWaitingQueue($worker); + } + } + + private function createWorker($image) + { + $worker = $this->pool->get(); + $worker->run($image, array($this, 'processDone')); + } + + public function processDone($worker) + { + $this->processing--; + $this->pool->dispose($worker); + + if (count($this->waitingQueue) > 0) { + $this->createWorker($this->popFromWaitingQueue()); + } + } + + private function pushToWaitingQueue($image) + { + $this->waitingQueue[] = $image; + } + + private function popFromWaitingQueue() + { + return array_pop($this->waitingQueue); + } + +} + diff --git a/Pool/README.md b/Pool/README.md new file mode 100644 index 0000000..b52fd87 --- /dev/null +++ b/Pool/README.md @@ -0,0 +1,9 @@ +Pool +==== + +The **object pool pattern** is a software creational design pattern that uses a set of initialized objects kept ready to use – a "pool" – rather than allocating and destroying them on demand. A client of the pool will request an object from the pool and perform operations on the returned object. When the client has finished, it returns the object, which is a specific type of factory object, to the pool rather than destroying it. + +Object pooling can offer a significant performance boost in situations where the cost of initializing a class instance is high, the rate of instantiation of a class is high, and the number of instances in use at any one time is low. The pooled object is obtained in predictable time when creation of the new objects (especially over network) may take variable time. + +However these benefits are mostly true for objects that are expensive with respect to time, such as database connections, socket connections, threads and large graphic objects like fonts or bitmaps. In certain situations, simple object pooling (that hold no external resources, but only occupy memory) may not be efficient and could decrease performance. + diff --git a/Pool/Worker.php b/Pool/Worker.php new file mode 100644 index 0000000..8ef0f79 --- /dev/null +++ b/Pool/Worker.php @@ -0,0 +1,22 @@ +process('image1.jpg'); +$processor->process('image2.jpg'); +$processor->process('image3.jpg'); +$processor->process('image4.jpg'); +$processor->process('image5.jpg'); +$processor->process('image6.jpg'); +$processor->process('image7.jpg'); +$processor->process('image8.jpg'); + diff --git a/README.md b/README.md index b34051e..35e565e 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ The patterns can be structured in roughly three different categories. Please cli * [FactoryMethod](FactoryMethod) [:notebook:](http://en.wikipedia.org/wiki/Factory_method_pattern) * [StaticFactory](StaticFactory) * [Prototype](Prototype) [:notebook:](http://en.wikipedia.org/wiki/Prototype_pattern) +* [Pool](Prototype) [:notebook:](http://en.wikipedia.org/wiki/Object_pool_pattern) * [Singleton](Singleton) [:notebook:](http://en.wikipedia.org/wiki/Singleton_pattern) (is considered an anti-pattern! :no_entry:) * [Multiton](Multiton) (is considered an anti-pattern! :no_entry:) diff --git a/Tests/Pool/PoolTest.php b/Tests/Pool/PoolTest.php new file mode 100644 index 0000000..0b86c5b --- /dev/null +++ b/Tests/Pool/PoolTest.php @@ -0,0 +1,32 @@ +get(); + + $this->assertEquals(1, $worker->id); + + $worker->id = 5; + $pool->dispose($worker); + + $this->assertEquals(5, $pool->get()->id); + $this->assertEquals(1, $pool->get()->id); + } + +} + From 6e937055cf5f66ea9337f96e85b036626c699b79 Mon Sep 17 00:00:00 2001 From: Jan Brecka Date: Tue, 8 Apr 2014 11:29:03 +0200 Subject: [PATCH 2/3] unifies indentation --- Pool/Pool.php | 25 ++++++++++++------------- Pool/Processor.php | 1 - Pool/README.md | 1 - Pool/Worker.php | 7 +++---- Pool/index.php | 1 - 5 files changed, 15 insertions(+), 20 deletions(-) diff --git a/Pool/Pool.php b/Pool/Pool.php index a38da74..32de053 100644 --- a/Pool/Pool.php +++ b/Pool/Pool.php @@ -5,7 +5,7 @@ namespace DesignPatterns\Pool; class Pool { - private $instances = array(); + private $instances = array(); private $class; public function __construct($class) @@ -13,19 +13,18 @@ class Pool $this->class = $class; } - public function get() - { - if (count($this->instances) > 0) { - return array_pop($this->instances); - } + public function get() + { + if (count($this->instances) > 0) { + return array_pop($this->instances); + } - return new $this->class(); - } + return new $this->class(); + } - public function dispose($instance) - { - $this->instances[] = $instance; - } + public function dispose($instance) + { + $this->instances[] = $instance; + } } - diff --git a/Pool/Processor.php b/Pool/Processor.php index a3cac2d..eabd51d 100644 --- a/Pool/Processor.php +++ b/Pool/Processor.php @@ -51,4 +51,3 @@ class Processor } } - diff --git a/Pool/README.md b/Pool/README.md index b52fd87..a39c3b2 100644 --- a/Pool/README.md +++ b/Pool/README.md @@ -6,4 +6,3 @@ The **object pool pattern** is a software creational design pattern that uses a Object pooling can offer a significant performance boost in situations where the cost of initializing a class instance is high, the rate of instantiation of a class is high, and the number of instances in use at any one time is low. The pooled object is obtained in predictable time when creation of the new objects (especially over network) may take variable time. However these benefits are mostly true for objects that are expensive with respect to time, such as database connections, socket connections, threads and large graphic objects like fonts or bitmaps. In certain situations, simple object pooling (that hold no external resources, but only occupy memory) may not be efficient and could decrease performance. - diff --git a/Pool/Worker.php b/Pool/Worker.php index 8ef0f79..2eb4126 100644 --- a/Pool/Worker.php +++ b/Pool/Worker.php @@ -11,12 +11,11 @@ class Worker // for example creates "thread" } - public function run($image, array $callback) - { + public function run($image, array $callback) + { // do something with $image... // and when it's done, execute callback call_user_func($callback, $this); - } + } } - diff --git a/Pool/index.php b/Pool/index.php index a41c492..3059efe 100644 --- a/Pool/index.php +++ b/Pool/index.php @@ -14,4 +14,3 @@ $processor->process('image5.jpg'); $processor->process('image6.jpg'); $processor->process('image7.jpg'); $processor->process('image8.jpg'); - From 65e48b2d306d282451aba96d300731c48e286363 Mon Sep 17 00:00:00 2001 From: Jan Brecka Date: Tue, 8 Apr 2014 11:29:40 +0200 Subject: [PATCH 3/3] typo --- Pool/Worker.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pool/Worker.php b/Pool/Worker.php index 2eb4126..4d34a0d 100644 --- a/Pool/Worker.php +++ b/Pool/Worker.php @@ -7,7 +7,7 @@ class Worker public function __construct() { - // let say that constuctor does really expensive work... + // let's say that constuctor does really expensive work... // for example creates "thread" }