Как выбрать паттерн и не злоупотреблять
Финальный урок: как выбрать нужный паттерн, распознать злоупотребление и куда двигаться после курса.
Зрелость в паттернах — это не «знать все 23», а понимать, когда паттерн не нужен. Лучший паттерн часто — никакого.
Антипаттерны: чего избегать
Антипаттерн — типовое решение, которое выглядит разумным, но приносит больше вреда, чем пользы. Несколько частых:
| Антипаттерн | Симптом |
| God Object | Один класс знает и делает всё — нарушение SRP |
| Golden Hammer | «Знаю Singleton — суну его везде»; один инструмент на все задачи |
| Pattern fever | Паттерны ради паттернов: фабрика фабрик, прокси над прокси |
| Spaghetti / Lasagna | Либо хаос связей, либо столько слоёв абстракции, что не докопаться до логики |
Алгоритм выбора паттерна
- Назови проблему. Что именно болит — создание объектов, склейка структур, взаимодействие? Это сразу даёт группу (см. урок о классификации).
- Проверь, есть ли изменчивость. Паттерн оправдан там, где будет меняться. Нет изменчивости — нет паттерна.
- Начни с простого. Функция, словарь, полиморфизм нередко решают задачу без «именного» паттерна.
- Применяй по «правилу трёх». Вводи паттерн, когда повторение стало реальным, а не гипотетическим.
Маленький «навигатор по симптомам» как памятка.
def suggest(symptom):
rules = {
"много if по типу": "Strategy или Factory Method",
"нужно уведомлять многих": "Observer",
"несовместимый чужой API": "Adapter",
"сложная подсистема": "Facade",
"undo/redo": "Command (+ Memento)",
"дерево объектов": "Composite",
}
return rules.get(symptom, "возможно, паттерн не нужен")
for s in ["много if по типу", "нужно уведомлять многих",
"undo/redo", "просто посчитать сумму"]:
print(f"{s} -> {suggest(s)}")
Вывод:
много if по типу -> Strategy или Factory Method нужно уведомлять многих -> Observer undo/redo -> Command (+ Memento) просто посчитать сумму -> возможно, паттерн не нужен
Обратите внимание на последнюю строку: для тривиальной задачи честный ответ — «паттерн не нужен». Это не поражение, а зрелость.
Признаки, что вы злоупотребляете
- Чтобы понять простую логику, приходится прыгать по пяти классам.
- Интерфейсы с единственной реализацией «на будущее», которое не наступает.
- Имя паттерна в названии класса важнее, чем его польза (
AbstractSingletonProxyFactoryBean). - Новый разработчик не может объяснить, зачем здесь этот слой.
Что дальше
Вы освоили словарь паттернов. Дальше углубляйтесь так:
- Рефакторинг. Паттерны редко проектируют заранее — к ним рефакторят, когда боль проявилась (книга Фаулера «Рефакторинг»).
- Принципы выше паттернов. SOLID, DRY, KISS, YAGNI — фундамент; паттерны лишь их инструменты.
- Архитектурные паттерны. Следующий масштаб — MVC, слоистая архитектура, гексагональная, событийная, микросервисы.
- Идиомы языка. В Python многие GoF-паттерны вырождаются в функции, декораторы, генераторы — учите идиомы своего языка.
Итог курса
- Паттерн — инструмент против изменчивости, а не самоцель.
- Выбор: назови проблему → проверь изменчивость → начни с простого → применяй по правилу трёх.
- Зрелость — знать, когда паттерн НЕ нужен; дальше — рефакторинг, принципы и архитектура.
Проверьте себя
1. Что такое антипаттерн?
AПаттерн для асинхронного кода
BТиповое решение, которое выглядит разумным, но вредит больше, чем помогает
CПаттерн без интерфейса
DЛюбой неизвестный паттерн
2. С чего стоит начинать выбор решения?
AСразу выбрать самый сложный паттерн
BНазвать проблему и проверить, есть ли реальная изменчивость
CДобавить интерфейсы на будущее
DСделать всё синглтонами
3. Какой главный признак зрелости в работе с паттернами?
AЗнать наизусть все 23
BПонимать, когда паттерн НЕ нужен
CИспользовать паттерн в каждом классе
DДавать классам имена паттернов