JavaRush /Курсы /Architecture & Logic /Антипаттерны

Антипаттерны

Architecture & Logic
2 уровень , 2 лекция
Открыта

Знакомство с анти-паттернами

Анти-паттерны — полная противоположность паттернам. Если паттерны — это рецепты "как готовить вкусно", то анти-паттерны — это список того, чего делать на кухне категорически нельзя, если не хотите отравить гостей.

Частью практик хорошего программирования является именно избежание анти-паттернов. Не надо думать, что это сухая теория — это грабли, на которые наступал каждый Senior-разработчик. Кто осведомлен, тот вооружён!

Рассмотрим классическую пятёрку анти-паттернов:

  • Магические числа и строки
  • Божественный объект (God Object)
  • Преждевременная оптимизация
  • Изобретение велосипеда
  • Изобретение квадратного колеса

Магические числа и строки

Магическое число — это константа (число или строка), которая встречается в коде без объяснения, что она значит.

if user.status == 2: # Что такое 2? Админ? Забанен? Мертв?
    do_something()

Когда в коде появляются такие числа, программист, который будет читать этот код через месяц (даже если это вы сами), потратит часы, пытаясь понять этот сакральный смысл.

Как лечить в Python:

  • Используйте константы с понятными именами (в верхнем регистре): STATUS_BANNED = 2.
  • Используйте Enums (модуль enum), который появился в Python 3.4. Это идеальное решение для статусов и типов.

God Object

Божественный объект — это класс, который знает слишком много, делает слишком много и хранит в себе почти все данные приложения. В Python этот антипаттерн часто мутирует в God Module.

Типичный пример студента — файл views.py или utils.py на 3000 строк, в котором перемешаны:

  • Регистрация пользователей
  • Отправка email
  • Генерация PDF-отчетов
  • Парсинг Excel

Такой код невозможно тестировать (приходится мокать половину вселенной), сложно читать и страшно менять.

Лечение: разбивайте задачи на подзадачи (Single Responsibility Principle). Логику работы с почтой — в services/email.py, отчеты — в services/reports.py.

Преждевременная оптимизация

Преждевременная оптимизация — это попытка сделать код быстрее до того, как вы доказали, что он работает медленно.

Дональд Кнут сказал: «Преждевременная оптимизация — корень всех зол».

Начинающие питонисты часто тратят часы, пытаясь переписать понятный цикл for на сложную конструкцию с map/filter/lambda, потому что "где-то слышали, что это быстрее". В итоге код становится нечитаемым, а выигрыш составляет 0.001 секунды.

Python-way:

  1. Сначала пишите чистый и читаемый код.
  2. Если код работает медленно — используйте профайлер (модуль cProfile или инструменты в PyCharm).
  3. Находите узкое место (часто это лишний запрос к БД, а не Python-код) и оптимизируйте только его.

Изобретение велосипеда

Смысл этого анти-паттерна: программист пишет свое решение задачи, для которой уже существует готовая, проверенная и оптимизированная библиотека.

Python славится своей философией "Батарейки в комплекте" и огромным репозиторием PyPI.

Примеры "велосипедов":

  • Писать свой парсер CSV вместо import csv.
  • Писать свои регулярки для проверки email вместо использования pydantic.EmailStr.
  • Писать свой клиент для HTTP-запросов на сокетах вместо import requests.

Ваше самописное решение почти наверняка будет содержать больше багов и работать медленнее, чем библиотека, которую сообщество полирует годами.

Изобретение велосипеда с квадратными колесами

Это усугубленная версия предыдущего пункта. Вы не просто изобретаете велосипед, вы изобретаете плохой велосипед.

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

Dependency Injection

Если «God Object» — это болезнь, то Dependency Injection — это лекарство. Это паттерн, который спасает проекты от превращения в «спагетти-код».

Проблема жесткой связи:

class UserService:
    def __init__(self):
        # ОШИБКА: Сервис сам создает подключение к БД.
        # Теперь вы не сможете протестировать этот сервис без реальной базы!
        self.db = PostgresDB("localhost", 5432)

Решение (DI):

class UserService:
    def __init__(self, db):
        # ПРАВИЛЬНО: Зависимость (db) передается извне.
        # В тестах вы сможете передать сюда "фейковую" базу (Mock).
        self.db = db

Пример в FastAPI:

Если вы работали с FastAPI, вы уже используете мощнейшую систему DI. Механизм Depends делает всю грязную работу за вас:

def read_users(db: Session = Depends(get_db)): ...

Фреймворк сам найдет, как создать подключение к БД, и «внедрит» его в вашу функцию. Это делает код чистым, модульным и легко тестируемым.

Хронология технологий

Чтобы вы понимали масштаб опыта, на который опираетесь:

  • Языки и стандарты:
    • SQL — 52 года (1974)
    • Python — 35 лет (1991)
    • HTTP — 35 лет (1991)
    • Java — 31 год (1995)
  • Инструменты Python-разработчика:
    • Django — 21 год (2005)
    • SQLAlchemy — 20 лет (2006)
    • Git — 21 год (2005)
    • Docker — 13 лет (2013)
    • FastAPI — 7 лет (2018)
  • Операционные системы:
    • Unix — 57 лет (1969)
    • Linux — 35 лет (1991)

Когда вам кажется, что вы придумали "уникальную" архитектуру для хранения настроек или работы с БД — скорее всего, вы просто не дочитали документацию к инструменту, которому уже 20 лет.

Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ