🎉 Ура! Після трьох років роботи, я нарешті випустив англійську версію книжки про патерни! Ось вона »
Одинак

Одинак на Python

Одинак — це породжуючий патерн, який гарантує існування тільки одного об’єкта певного класу, а також дозволяє дістатися цього об’єкта з будь-якого місця програми.

Одинак має такі ж переваги та недоліки, що і глобальні змінні. Його неймовірно зручно використовувати, але він порушує модульність вашого коду.

Ви не зможете просто взяти і використовувати клас, залежний від одинака, в іншій програмі. Для цього доведеться емулювати там присутність одинака. Найчастіше ця проблема проявляється при написанні юніт-тестів.

Детальніше про Одинака

Особливості паттерна на Python

Складність:

Популярність:

Застосування: Багато програмістів вважають Одинака антипатерном, тому його все рідше і рідше можна зустріти в Python-коді.

Ознаки застосування патерна: Одинака можна визначити за статичним створюючим методом, який повертає один і той же об’єкт.

Наївний Одинак

Незграбно реалізувати Одинака дуже просто — достатньо приховати конструктор і надати створюючий статичний метод.

Той же клас веде себе неправильно в багатопотоковому середовищі. Декілька потоків можуть одночасно викликати метод отримання Одинака та створити відразу кілька екземплярів об’єкта.

main.py: Приклад структури патерна

from __future__ import annotations
from typing import Optional


class Singleton:
    """
    The Singleton class defines the `getInstance` method that lets clients
    access the unique singleton instance.
    """

    _instance: Optional<a href="/uk/design-patterns/singleton">Одинак</a> = None

    def __init__(self) -> None:
        if Singleton._instance is not None:
            raise ReferenceError("Cannot instantiate a singleton class.")
        else:
            Singleton._instance = self

    @staticmethod
    def get_instance() -> Singleton:
        """
        The static method that controls the access to the singleton instance.
        
        This implementation let you subclass the Singleton class while
        keeping just one instance of each subclass around.
        """

        if not Singleton._instance:
            Singleton()
        return Singleton._instance

    def some_business_logic(self):
        """
        Finally, any singleton should define some business logic, which can
        be executed on its instance.
        """

        # ...


if __name__ == "__main__":
    # The client code.

    s1 = Singleton.get_instance()
    s2 = Singleton.get_instance()

    if id(s1) == id(s2):
        print("Singleton works, both variables contain the same instance.")
    else:
        print("Singleton failed, variables contain different instances.")

Output.txt: Результат виконання

Singleton works, both variables contain the same instance.

Одинак in Other Languages

Одинак in Java Одинак in C# Одинак in PHP Одинак in TypeScript