Multiton design pattern /Registry of Singletons/

Този Design Pattern е така да се каже разширение на Singleton Design Pattern и също е известна като „Registry of Singletons“.

В смисъл такъв, че Singleton гарантира само един обект от даденият клас, а Multiton – повече от един обект от СЪЩИЯТ клас, но съдържащи се в хеш таблица или масив на друг обект.
…the multiton pattern instead ensures a single instance per key.

Представете си го като асоциативен масив с много съставки от дадена кулинарна рецепта, но от съставка можем да имаме само по една:

static private $ingredients = null;

...

self::$ingredients['tomato'] = Ingredients.getInstance('tomato');
self::$ingredients['pepper'] = Ingredients.getInstance('pepper');
self::$ingredients['cheese'] = Ingredients.getInstance('cheese');

...

и разбира се за всяка съставка, трябва първо да проверяваме дали вече не е добавена, тоест, дали вече имаме стойност в масива $shopskaSalad за даденият ключ.

...

if (self::$ingredients['tomato'] === null)
    self::$ingredients['tomato'] = Ingredients.getInstance('tomato');

if (self::$ingredients['pepper'] === null)
    self::$ingredients['pepper'] = Ingredients.getInstance('pepper');

if (self::$ingredients['cheese'] === null)
    self::$ingredients['cheese'] = Ingredients.getInstance('cheese');

...

As the name suggests, a multiton is a design pattern that helps you create multiple instances of itself. Both singleton and multiton are same, the only difference is that a multiton can store and retrieve multiple instances of itself. Obviously multiton suffers from same problems as singletons.

Here is example of multiton:

class Logger
{
    private static $instances = array();

    public static function getInstance(string $key): self
    {
        if (!array_key_exists($key, self::$instances)) {
            self::$instances[$key] = new self();
        }
        return self::$instances[$key];
    }

    // prevent creating multiple instances due to "private" constructor
    private function __construct(){}

    // prevent the instance from being cloned
    private function __clone(){}

    // prevent from being unserialized
    public function __wakeup(){}
}

$firstInstance = Logger::getInstance('file');
$secondInstance = Logger::getInstance('email');

Литература:

https://en.wikipedia.org/wiki/Multiton_pattern

https://www.codeproject.com/Articles/1178694/Singleton-and-Multiton-Pattern

https://codeinphp.github.io/post/singleton-and-multiton-design-patterns/