1.4. Пул об’єктів (Pool)
1.4.1. Призначення
Патерн, що породжує, який надає набір заздалегідь ініціалізованих об’єктів, готових до використання («пул»), що не вимагає щоразу створювати та знищувати їх.
Зберігання об’єктів у пулі може помітно підвищити продуктивність у ситуаціях, коли вартість та швидкість ініціалізації екземпляра класу високі, а кількість екземплярів, що одночасно використовуються, в будь-який момент часу є низьким. Час отримання об’єкта з пулу легко прогнозується, як створення нового об’єкта (особливо з мережевим оверхедом) може займати невизначений час.
Однак ці переваги в основному відносяться до об’єктів, які спочатку є дорогими за часом створення. Наприклад, з’єднання з базою даних, з’єднання сокетів, потоків або ініціалізація великих графічних об’єктів, таких як шрифти або растрові зображення. У деяких ситуаціях, використання простого пулу об’єктів (які не залежать від Зовнішніх ресурсів, а тільки займають пам’ять) може виявитися неефективним і приведе до зниження продуктивності.
1.4.2. Діаграма UML
1.4.3. Код
Ви можете знайти цей код на GitHub
WorkerPool.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Creational\Pool;
6
7use Countable;
8
9class WorkerPool implements Countable
10{
11 /**
12 * @var StringReverseWorker[]
13 */
14 private array $occupiedWorkers = [];
15
16 /**
17 * @var StringReverseWorker[]
18 */
19 private array $freeWorkers = [];
20
21 public function get(): StringReverseWorker
22 {
23 if (count($this->freeWorkers) === 0) {
24 $worker = new StringReverseWorker();
25 } else {
26 $worker = array_pop($this->freeWorkers);
27 }
28
29 $this->occupiedWorkers[spl_object_hash($worker)] = $worker;
30
31 return $worker;
32 }
33
34 public function dispose(StringReverseWorker $worker): void
35 {
36 $key = spl_object_hash($worker);
37 if (isset($this->occupiedWorkers[$key])) {
38 unset($this->occupiedWorkers[$key]);
39 $this->freeWorkers[$key] = $worker;
40 }
41 }
42
43 public function count(): int
44 {
45 return count($this->occupiedWorkers) + count($this->freeWorkers);
46 }
47}
StringReverseWorker.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Creational\Pool;
6
7class StringReverseWorker
8{
9 public function run(string $text): string
10 {
11 return strrev($text);
12 }
13}
1.4.4. Тест
Tests/PoolTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Creational\Pool\Tests;
6
7use DesignPatterns\Creational\Pool\WorkerPool;
8use PHPUnit\Framework\TestCase;
9
10class PoolTest extends TestCase
11{
12 public function testCanGetNewInstancesWithGet()
13 {
14 $pool = new WorkerPool();
15 $worker1 = $pool->get();
16 $worker2 = $pool->get();
17
18 $this->assertCount(2, $pool);
19 $this->assertNotSame($worker1, $worker2);
20 }
21
22 public function testCanGetSameInstanceTwiceWhenDisposingItFirst()
23 {
24 $pool = new WorkerPool();
25 $worker1 = $pool->get();
26 $pool->dispose($worker1);
27 $worker2 = $pool->get();
28
29 $this->assertCount(1, $pool);
30 $this->assertSame($worker1, $worker2);
31 }
32}