Programming

Паттерны проектирования

Паттерны проектирования — типовые проверенные решения повторяющихся задач в архитектуре кода, описанные как схема классов, а не как готовая библиотека.

Что такое Паттерны проектирования

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

Термин пришёл в программирование из архитектуры зданий (Кристофер Александер), а закрепила его книга «Design Patterns» 1994 года четырёх авторов, которых называют Gang of Four (GoF). Описанные там 23 паттерна до сих пор составляют базовый словарь.

Главная польза паттернов — общий язык. Фраза «сделай тут фабрику, а уведомления через наблюдателя» заменяет полчаса объяснений на код-ревью.

Три группы паттернов GoF

Группа Задача Примеры
Порождающие Как создавать объекты Singleton, Factory Method, Abstract Factory, Builder, Prototype
Структурные Как собирать объекты в структуры Adapter, Decorator, Facade, Proxy, Composite, Bridge, Flyweight
Поведенческие Как объекты взаимодействуют Strategy, Observer, Command, Iterator, State, Template Method, Chain of Responsibility

Strategy — самый полезный на практике

Взаимозаменяемые алгоритмы за одним интерфейсом. Убирает ветвление if/elif по типу и позволяет расширять поведение, не трогая существующий код:

from abc import ABC, abstractmethod

class PaymentStrategy(ABC):
    @abstractmethod
    def pay(self, amount: int) -> str: ...

class CardPayment(PaymentStrategy):
    def pay(self, amount: int) -> str:
        return f"Списано {amount} с карты"

class SbpPayment(PaymentStrategy):
    def pay(self, amount: int) -> str:
        return f"Оплачено {amount} через СБП"

class Order:
    def __init__(self, strategy: PaymentStrategy) -> None:
        self.strategy = strategy

    def checkout(self, amount: int) -> str:
        return self.strategy.pay(amount)

Order(SbpPayment()).checkout(1500)

Новый способ оплаты — новый класс; Order остаётся нетронутым. Это ровно то, чего требует принцип open/closed из SOLID.

Ещё три, которые встречаются каждый день

Adapter — прослойка, переводящая чужой интерфейс в ожидаемый вашим кодом. Классический случай: подменить внешний платёжный шлюз, не переписывая половину приложения.

Facade — один простой вход в сложную подсистему. requests.get(url) — фасад над сокетами, TLS, редиректами и кодировками.

Observer — объект уведомляет подписчиков об изменениях, не зная, кто они. На этом построены слушатели событий в браузере, сигналы Django и подписка на очередь задач: издатель просто вызывает emit("order.paid", ...), а сколько обработчиков за этим стоит — письмо, проводка, аналитика — его не касается.

Что такое антипаттерн

Антипаттерн — решение, которое выглядит естественным, применяется часто и стабильно делает хуже. Это не «плохой код вообще», а именно повторяющаяся ловушка с собственным именем:

  • God Object — класс на три тысячи строк, знающий про всё. Любая правка задевает всех.
  • Spaghetti code — поток управления без структуры, читается только пошаговой отладкой.
  • Golden Hammer — «я знаю паттерн X», после чего X применяется ко всему подряд.
  • Copy-paste programming — дублирование вместо выделения общего: баг чинится в одном месте из семи.
  • Premature optimization — усложнение ради выигрыша, который никто не измерял.
  • Singleton как глобальная переменная — сам Singleton давно спорный: он прячет зависимости и ломает тесты.

Когда паттерны вредят

Паттерн — ответ на существующую проблему, а не украшение. Три интерфейса, фабрика и стратегия там, где хватало функции на десять строк, — это тот же Golden Hammer, только с уважаемым названием.

Разумный порядок: пишем простое решение → появляется вторая и третья вариация → узнаём в этом паттерн → рефакторим. Не наоборот. И половина паттернов GoF в языках с функциями первого класса схлопывается: Strategy в Python часто просто функция, переданная аргументом.

Связанные термины

  • SOLID — принципы, из которых вырастает большинство паттернов
  • Концепции разработки — DRY, KISS, идемпотентность и прочая база
  • Java — язык, на примерах которого писалась книга GoF
  • Микросервисы и монолит — паттерны уровня архитектуры системы
  • Code review — где словарь паттернов экономит время

Готовы запустить GPU-задачу?

Запустить GPU-сервер