Что такое принцип DRY в разработке?

Ответ

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

Почему это важно:

  • Снижение стоимости поддержки: Изменение требуется внести только в одном месте.
  • Уменьшение ошибок: Исправление в одном месте гарантирует, что логика будет исправлена везде.
  • Повышение читаемости: Код становится менее раздутым и более понятным.
  • Облегчение тестирования: Логика, сосредоточенная в одном месте, проще покрывается тестами.

Пример нарушения и исправления:

// НАРУШЕНИЕ DRY: Одна и та же формула расчёта налога дублируется.
class OrderProcessor {
    public function calculateTax($amount) {
        return $amount * 0.20; // Логика налога 20%
    }
}

class InvoiceGenerator {
    public function calculateTax($amount) {
        return $amount * 0.20; // Та же самая логика налога
    }
}
// СОБЛЮДЕНИЕ DRY: Логика вынесена в единственный авторитетный источник.
class TaxCalculator {
    private const TAX_RATE = 0.20;

    public static function calculate($amount) {
        return $amount * self::TAX_RATE;
    }
}

class OrderProcessor {
    public function calculateTax($amount) {
        return TaxCalculator::calculate($amount);
    }
}

class InvoiceGenerator {
    public function calculateTax($amount) {
        return TaxCalculator::calculate($amount);
    }
}

Важный нюанс: Принцип DRY применяется к знанию и бизнес-логике, а не к случайно похожему коду. Иногда структурное дублирование кода (например, шаблонные методы в разных классах) менее вредно, чем создание неправильной, чрезмерно сложной абстракции только ради устранения повторения.

Ответ 18+ 🔞

Слушай, а вот есть такая штука в программировании — DRY. Расшифровывается как «Don't Repeat Yourself», что в переводе на наш могучий означает «Не повторяйся, ёпта». Суть проще пареной репы, но её постоянно наступают на грабли.

Представь, у тебя есть знание, какая-то важная логика. Например, как посчитать этот чёртов налог. Так вот, это знание должно жить в одном-единственном священном месте в твоей системе. Один раз объявил — и все туда ходят спрашивать, как правильно. Если ты начинаешь копировать эту логику из класса в класс, ты обрекаешь себя на адскую жизнь. Потому что когда ставка налога поменяется (а она всегда меняется, ядрёна вошь!), тебе придётся бегать по всему коду и править её в двадцати местах. И гарантированно где-то забудешь, и получится пиздец и расхождения в отчётах. Доверия к такому коду — ноль ебать.

Пример, где всё пошло по пизде:

Смотри, вот два класса, которые делают вид, что не знают друг о друге.

// НАРУШЕНИЕ DRY: Одна и та же формула расчёта налога дублируется.
class OrderProcessor {
    public function calculateTax($amount) {
        return $amount * 0.20; // Логика налога 20%
    }
}

class InvoiceGenerator {
    public function calculateTax($amount) {
        return $amount * 0.20; // Та же самая логика налога
    }
}

Видишь? Одна и та же магическая цифра 0.20 забита в двух местах. Это как хранить один и тот же пароль на двух бумажках в разных комнатах — рано или поздно одну обновят, а вторую забудут, и будет тебе волнение ебать.

А вот как надо, по-человечески:

Выносим это знание куда подальше, в отдельный сервис. Пусть он один отвечает за налоги, а все остальные — его клиенты.

// СОБЛЮДЕНИЕ DRY: Логика вынесена в единственный авторитетный источник.
class TaxCalculator {
    private const TAX_RATE = 0.20;

    public static function calculate($amount) {
        return $amount * self::TAX_RATE;
    }
}

class OrderProcessor {
    public function calculateTax($amount) {
        return TaxCalculator::calculate($amount);
    }
}

class InvoiceGenerator {
    public function calculateTax($amount) {
        return TaxCalculator::calculate($amount);
    }
}

Теперь, когда начальство прикажет поменять налог на 18%, ты идёшь в один-единственный класс TaxCalculator, меняешь константу TAX_RATE на 0.18 — и вся система автоматом начинает считать правильно. Красота, да? Чихать тебе в сраку, а не бегать с поиском по проекту.

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

Видео-ответы