Какие основные паттерны проектирования часто используются в Python?

Ответ

В Python-разработке активно применяются различные паттерны проектирования для создания гибкого, масштабируемого и поддерживаемого кода. Ниже представлены некоторые из наиболее часто используемых:

  1. Singleton (Одиночка)

    • Назначение: Гарантирует, что у класса есть только один экземпляр, и предоставляет глобальную точку доступа к нему.
    • Применение: Используется для объектов, которые должны быть уникальными в системе, например, менеджеры конфигурации, пулы соединений или логирование.

      
      class Singleton:
      _instance = None
      
      def __new__(cls):
          if not cls._instance:
              cls._instance = super().__new__(cls)
          return cls._instance

    Пример использования:

    s1 = Singleton() s2 = Singleton() print(s1 is s2) # Выведет True

  2. Factory Method (Фабричный метод)

    • Назначение: Определяет интерфейс для создания объекта, но позволяет подклассам решать, какой класс инстанцировать. Делегирует создание объектов подклассам.
    • Применение: Используется, когда класс не может предвидеть класс объектов, которые ему нужно создать, или когда подклассы должны определять, какие объекты создавать.
      
      from abc import ABC, abstractmethod

    class Product(ABC): @abstractmethod def operation(self): pass

    class ConcreteProduct(Product): def operation(self): return "ConcreteProduct operation"

    class Creator(ABC): @abstractmethod def factory_method(self) -> Product: pass

    class ConcreteCreator(Creator): def factory_method(self) -> Product: return ConcreteProduct()

    Пример использования:

    creator = ConcreteCreator() product = creator.factory_method() print(product.operation())

  3. Observer (Наблюдатель)

    • Назначение: Определяет зависимость "один-ко-многим" между объектами так, что при изменении состояния одного объекта все зависящие от него оповещаются и автоматически обновляются.
    • Применение: Используется для реализации распределенных систем событий, где изменения в одном объекте должны вызывать действия в других, не связывая их напрямую.

      
      class Subject:
      def __init__(self):
          self._observers = []
      
      def attach(self, observer):
          if observer not in self._observers:
              self._observers.append(observer)
      
      def detach(self, observer):
          self._observers.remove(observer)
      
      def notify(self, message):
          for observer in self._observers:
              observer.update(message)

    class Observer: def init(self, name): self.name = name

    def update(self, message):
        print(f"Observer {self.name} received: {message}")

    Пример использования:

    subject = Subject() observer1 = Observer("One") observer2 = Observer("Two")

    subject.attach(observer1) subject.attach(observer2)

    subject.notify("State changed!")

  4. Decorator (Декоратор)

    • Назначение: Динамически добавляет новую функциональность объекту, не изменяя его структуру. В Python реализуется с помощью функций-декораторов или классов.
    • Применение: Идеален для добавления логирования, кэширования, проверки прав доступа, измерения времени выполнения и других сквозных функций.
      
      def logger(func):
      def wrapper(*args, **kwargs):
          print(f"[LOG] Calling function: {func.__name__} with args: {args}, kwargs: {kwargs}")
          result = func(*args, **kwargs)
          print(f"[LOG] Function {func.__name__} returned: {result}")
          return result
      return wrapper

    @logger def add(a, b): return a + b

    Пример использования:

    print(add(2, 3))

Помимо перечисленных, в Python также часто используются другие паттерны, такие как Adapter (Адаптер), Strategy (Стратегия), Facade (Фасад), Iterator (Итератор) и Template Method (Шаблонный метод).