Баланс и DRY (Don't Repeat Yourself)


Многие считают, что DRY запрещает дублировать код, но это не так. Вся суть таится немного глубже. Давайте разберемся с определением:

"Каждая часть знания должна иметь единственное, непротиворечивое и авторитетное представление в рамках системы"

Вся тайна кроется как раз в определении "часть знания". Что же это такое?

Речь идёт не о написанном коде, а о знаниях в "предметной области" или "бизнес правилах". Давайте рассмотрим пример

final class Basket
{
    private const MAX_PRODUCTS_ALLOWED = 3;

    private $products;

    public function addProduct($product)
    {
        if (self::MAX_PRODUCTS_ALLOWED === count($this->products)) {
            throw new Exception('Max 3 products allowed');
        }
        $this->products[] = $product;
    }
}

final class Shipment
{
    private const MAX_PRODUCTS_ALLOWED = 3;

    private $products;

    public function addProduct($product)
    {
        if (self::MAX_PRODUCTS_ALLOWED === count($this->products)) {
            throw new Exception('Max 3 products allowed');
        }
        $this->products[] = $product;
    }
}
В данном случае код выглядит одинаково, однако, это может продиктовано абсолютно разными требованиями бизнеса:

  • Мы ограничиваем корзину тремя единицами товара из-за высокого спроса, а нам выгодно продать его как можно большему кол-ву покупателей.
  • В то же время мы ограничиваем доставку тремя единицами, потому что наш транспорт физически не может вместить большего объема.
Подсознательно нам хочется взять и вынести дублирующийся код в один источник, но что если какое-то из правил изменится? Например мы купили новый транспорт для доставки и теперь можем доставлять до 10 единиц товара?

Очень важно, чтобы у вашего кода могла быть только "одна причина для изменения" (прямо как в SRP), ведь правила вашего бизнеса в одной предметной области могут (и должны) меняться независимо от другой.

Когда-то М. Фаулер популяризировал так называемое Rule of three. Звучит примерно так: "Два экземпляра аналогичного кода не требуют рефакторинга, но, когда аналогичный код используется три раза, его следует извлечь в новую процедуру." Это правило, в первую очередь, отлично помогает избежать преждевременного обобщения, когда с виду похожие вещи имеют разные зоны ответственности и потому не являются дублированием.

DRY — это принцип, однако принципы — не правила. Они лишь инструменты, помогающие идти в правильном направлении. Очевидно, что не стоит везде повторять бизнес-логику, но также не нужно и объединять всё подряд. Необходимо искать баланс, который зависит от текущей ситуации.
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегизаметки, php, DRY




Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.



PHP изображения, графики
Слежение за участком экрана на C#
Программа "Новогодняя ёлочка"