Что такое принцип DRY в программировании?

Ответ

DRY (Don't Repeat Yourself) — фундаментальный принцип разработки, направленный на устранение дублирования логики в кодовой базе. Его суть: каждая часть знания или логики должна иметь единственное, однозначное представление в системе.

Проблема дублирования:

# НАРУШЕНИЕ DRY: одинаковая логика расчета налога разбросана по функциям
def calculate_total_with_tax_a(amount):
    tax_rate = 0.20
    return amount * (1 + tax_rate)

def calculate_total_with_tax_b(amount):
    tax_rate = 0.20  # Дублирование значения и формулы
    return amount * (1 + tax_rate)

Решение по принципу DRY:

# 1. Выносим "знание" (ставку налога) в константу
TAX_RATE = 0.20

# 2. Создаем единственную функцию с этой логикой
def apply_tax(amount, rate=TAX_RATE):
    return amount * (1 + rate)

# 3. Переиспользуем ее
total_a = apply_tax(100)
total_b = apply_tax(200)

Практические применения:

  • В тестировании: Вынос общих шагов (авторизация, подготовка данных) в фикстуры (pytest), хуки (@BeforeEach) или Page Object методы.
  • В коде: Создание утилитарных функций/классов, использование миксинов, наследование.
  • В конфигурации: Централизованное хранение констант, URL, учетных данных.

Важно: DRY — это не про устранение любого похожего кода, а про устранение дублирования логики и знаний. Слепое объединение всего может привести к чрезмерно связанному и сложному коду.

Ответ 18+ 🔞

Ну и что мы тут имеем, а? О, смотри-ка, священный грааль для любого программиста, который не хочет, чтобы его код превратился в помойку — принцип DRY (Don't Repeat Yourself). Суть проще пареной репы, но, блядь, её так часто игнорируют, что диву даёшься! Каждая единица знания, каждая логическая операция в системе должна существовать в одном-единственном месте. Один раз написал, один раз проверил, один раз выеб*лся с ней — и везде используешь. Всё, пиздец, конец истории.

Вот смотри, как бывает, когда по этому принципу плюют с высокой колокольни:

# НАРУШЕНИЕ DRY: одинаковая логика расчета налога разбросана по функциям
def calculate_total_with_tax_a(amount):
    tax_rate = 0.20
    return amount * (1 + tax_rate)

def calculate_total_with_tax_b(amount):
    tax_rate = 0.20  # Дублирование значения и формулы
    return amount * (1 + tax_rate)

Видишь эту дичь? Магическое число 0.20 и формула amount * (1 + tax_rate) кочуют из функции в функцию. Захотел поменять ставку налога — иди, сука, ползай по всему коду, как таракан, и меняй вручную. Один раз забудешь — и привет, баг в продакшене. Терпения ебать ноль на такое!

А теперь правильный подход, когда мозги включены:

# 1. Выносим "знание" (ставку налога) в константу. Одно место на весь мир!
TAX_RATE = 0.20

# 2. Создаем единственную функцию с этой логикой. Одна функция на все случаи жизни!
def apply_tax(amount, rate=TAX_RATE):
    return amount * (1 + rate)

# 3. Переиспользуем её, как последнюю спичку в тюрьме. Легко и изящно!
total_a = apply_tax(100)
total_b = apply_tax(200)

Вот теперь красота! Изменил TAX_RATE в одном месте — и вся программа подхватила новое значение. Формула тоже одна. Хуй с горы, а не поддержка!

Где это применить, чтобы не выглядеть мартышкой с гранатой?

  • В тестировании: Не пишешь же ты каждый раз в каждом тесте шаги авторизации? Выносишь в фикстуру или хук — и потом просто юзаешь. Page Object — это вообще песня, чтобы не дублировать селекторы.
  • В коде: Увидел, что один и тот же кусок логики всплывает в двух разных классах — выноси в базовый класс или утилитарный модуль. Не изобретай велосипед каждый раз!
  • В конфигурации: URL-ы, пароли, таймауты — всё это должно лежать в одном конфиге, а не быть раскидано по скриптам, как говно по тарелкам.

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