Пул одинаків (англ. Multiton) - схожий на шаблон Одинак.
Дозволяє створювати та утримувати кілька одинаків, доступ до яких можна отримати за унікальним “ключем”.
Продовжуємо тему нашої закусочної. Бізнес йде в гору, і ми встановлюємо ще кілька касових апаратів.
Для зручного доступу до всіх апаратів ми створимо систему ShopCashSystem, яку і реалізує наш Multiton.
Як і з Singleton, ми закрили всі магічні методи. Для доступу до об’єкта використовується
статичний метод ShopCashSystem::getInstance()
.
Застосування:
- Два об’єкти для доступу до баз даних, наприклад, один для MySQL, а другий для SQLite
- Декілька логуючих об’єктів (один для налагоджувальних повідомлень, інший для помилок тощо)
Примітка: Іноді цей шаблон називають Реєстр одинаків. Нагадаю про антипаттерн Самотність (Singletonitis).
-
MultitonInterface.php
<?php namespace DesignPatterns\Creational\Multiton; /** * Interface MultitonInterface * @package DesignPatterns\Creational\Multiton */ interface MultitonInterface { /** * @param string $instanceName * * @return MultitonInterface */ public static function getInstance(string $instanceName): self; }
-
ShopCashSystem.php
<?php namespace DesignPatterns\Creational\Multiton; use DesignPatterns\Creational\Singleton\CashboxTrait; /** * Class ShopCashSystem * @package DesignPatterns\Creational\Multiton */ class ShopCashSystem implements MultitonInterface { use CashboxTrait; /** * @var MultitonInterface[] */ private static $instances = []; /** * Return Singleton instance * * @param string $instanceName * * @return MultitonInterface */ public static function getInstance(string $instanceName): MultitonInterface { if (!isset(self::$instances[$instanceName])) { self::$instances[$instanceName] = new self(); } return self::$instances[$instanceName]; } private function __construct() { } private function __clone() { } private function __wakeup() { } }
Test case:
MultitonTest.php
<?php
namespace DesignPatterns\Tests\Creational\Multiton;
use DesignPatterns\Creational\Multiton\ShopCashSystem;
use PHPUnit_Framework_TestCase;
class MultitonTest extends PHPUnit_Framework_TestCase
{
public function testUniqueness()
{
$firstCashbox = ShopCashSystem::getInstance('Cashbox#1');
$secondCashbox = ShopCashSystem::getInstance('Cashbox#2');
$this->assertInstanceOf('DesignPatterns\Creational\Multiton\MultitonInterface', $firstCashbox);
$this->assertInstanceOf('DesignPatterns\Creational\Multiton\MultitonInterface', $secondCashbox);
$this->assertNotSame($firstCashbox, $secondCashbox);
$thirdCashbox = ShopCashSystem::getInstance('Cashbox#1');
$this->assertSame($firstCashbox, $thirdCashbox);
$firstCashbox->setCash(5);
$this->assertSame($firstCashbox, $thirdCashbox);
}
}