Что такое паттерны проектирования и зачем они нужны

«Что такое паттерны проектирования и зачем они нужны» — вопрос из категории Паттерны, который задают на 10% собеседований Python Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Паттерны проектирования (Design Patterns) — это переиспользуемые, проверенные временем решения типичных проблем, возникающих при проектировании программного обеспечения. Они не являются конкретными алгоритмами или библиотеками, а представляют собой концептуальные шаблоны и рекомендации.

Основные цели использования паттернов:

  1. Общий словарь: Паттерны предоставляют разработчикам общий язык для обсуждения архитектурных решений. Сказать «здесь используем Фабрику» гораздо быстрее и точнее, чем описывать всю структуру классов с нуля.
  2. Проверенные решения: Они аккумулируют опыт тысяч разработчиков, позволяя избежать распространенных ошибок и «изобретения велосипедов».
  3. Улучшение структуры кода: Применение паттернов способствует созданию более гибкого, поддерживаемого и масштабируемого кода, часто за счет уменьшения связанности (low coupling) и увеличения сплоченности (high cohesion) компонентов.

Пример: паттерн Singleton (Одиночка)

Проблема: Необходимо гарантировать, что у класса будет только один экземпляр, и предоставить к нему глобальную точку доступа (например, для подключения к базе данных или логгера).

Решение:

class DatabaseConnection:
    _instance = None

    def __new__(cls, *args, **kwargs):
        # __new__ вызывается перед __init__
        if not cls._instance:
            # Если экземпляр еще не создан, создаем его
            cls._instance = super().__new__(cls)
        # Возвращаем всегда один и тот же экземпляр
        return cls._instance

    def __init__(self):
        # Инициализация может происходить несколько раз,
        # поэтому здесь не должно быть логики, выполняемой единожды.
        print("Initializing connection...")

# Проверка
db1 = DatabaseConnection()
db2 = DatabaseConnection()

print(f"db1 is db2: {db1 is db2}") # Вывод: db1 is db2: True

Важное предостережение

Ключевой принцип — не применять паттерны ради паттернов. Чрезмерное или неуместное их использование приводит к усложнению кода (over-engineering). Решение без паттерна, если оно простое и понятное, часто является лучшим выбором.