Хранение нескольких экземпляров на синглтоне?

Хранение нескольких экземпляров на синглтоне?
Хранение нескольких экземпляров на синглтоне? - kamrog @ Unsplash

Вы искажаете то, что написал цитируемый автор, а именно:

class SingletonMeta(type):

    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            instance = super().__call__(*args, **kwargs)
            cls._instances[cls] = instance
        return cls._instances[cls]


class Singleton(metaclass=SingletonMeta):
    def some_business_logic(self):
        ...

Вызываем ли мы SingletonMeta() ? Нет. Автор присваивает s1 = Singleton(), и аналогично s2. Это совсем другое.

Паттерн синглтона был абстрагирован, поэтому он едва появляется в классе с бизнес-логикой. Достаточно лишь краткого упоминания metaclass=SingletonMeta, чтобы втянуть его.

Почему необходим dict контейнер? Потому что метакласс поддерживает несколько дочерних классов. Вот несколько примеров, которые автор не предложил.

class WaffleSingleton(metaclass=SingletonMeta):
    def make_waffles(self):
        ...

class PancakeSingleton(metaclass=SingletonMeta):
    def make_pancakes(self):
        ...

В любом случае, на данный момент дикт метакласса будет содержать три записи. Обратите внимание, что каждый из этих классов может быть размещен в отдельном модуле, но общий импорт SingletonMeta организует для них обновление одного и того же dict.


Упомянутый вами подход вполне осуществим. Это просто больше copy-n-paste boilerplate в каждом классе, который смотрит вам в лицо. Цель the metaclass approach была в том, чтобы быть минимально навязчивым, чтобы инженеры могли сосредоточиться на бизнес-логике.

Рекомендую посмотреть эти видео для лучшего погружения в вопрос:

Прикрепленное видео 1 - Урок 02. PHP - Design Patterns. Singleton. Multione container

Прикрепленное видео 2 - Java - урок 24.1 (Паттерн Singleton. Или как создать лишь один объект класса)


LetsCodeIt, 19 февраля 2023 г., 16:29