Паттерны проектирования
Паттерны проектирования — типовые проверенные решения повторяющихся задач в архитектуре кода, описанные как схема классов, а не как готовая библиотека.
Что такое Паттерны проектирования
Паттерн (шаблон) проектирования — типовое решение часто встречающейся задачи проектирования, описанное в отрыве от конкретного языка. Это не библиотека и не кусок кода, который копируют: это схема — какие сущности завести, как они связаны и почему именно так.
Термин пришёл в программирование из архитектуры зданий (Кристофер Александер), а закрепила его книга «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-сервер