Принцип DRY

| April 14, 2022

В этой статье речь пойдёт об одном из самых простых принципов, которые вы с лёгкостью сможете изучить и указать в своём резюме. Это принцип - DRY.

Что такое DRY?

Акроним DRY расшифровывается как Don’t Repeat Yourself, что переводится как “Не повторяйся”.

В разработке программного обеспечения, этот принцип применяется для снижения повторение информации различного рода, особенно в системах со множество слоёв абстрагирования.

Принцип DRY формулируется как: “Каждая часть знания должна иметь единственное, непротиворечивое и авторитетное представление в рамках системы”.

Чем DRY не является?

Принцип DRY точно не является “однобоким” правилом, запрещающим копирование классов и методов в рамках одного проекта. На самом деле, это лишь небольшая часть этого принципа. На деле же, идеи DRY куда глубже.

Принцип DRY точно не является “однобоким” правилом, запрещающим копирование классов и методов в рамках одного проекта.

Единый Источник Достоверности

Принцип DRY это про Единый Источник Достоверности любого знания в системе (то, что в английском языке называется - Single Source of Truth). В качестве знания, подразумевается всё, что относится к программной системе. Не обязательно только код.

Применительно к коду, примером нарушения принципа может быть банальное копирование одного и того же метода в рамках одного приложения. Например, метод для суммирования двух целых числе, может быть определён в двух разных классах:

/**
 * Математические функции.
 */
public class MathUtils {
    public static int sum(int a, int b) { 
        return a + b;
    }
}

/**
 * Сервис расчёта зарплат.
 */
public class SalaryService {
    public int sum(int base, int compensation) {
        return base + compensation;
    }
}

Первый класс-утилита содержит методы для работы с математическими функциями. Второй - методы для расчётов зарплат. Реализация и интерфейс методов идентичны. С одной стороны, ничего страшного тут нет. MathUtils содержит математические операции, не привязанные к бизнесу, а значит метод со сложением находится в нужном месте. SalaryService же, напротив, содержит сложение, но привязанное к требованиям бизнеса. Это оправдывает наличие двух методов, выполняющих одно и то же.

А теперь представим, что оба класса, и, соответсвенно, их метода используются для расчёта зарплат в разных местах программной системы. В таком случае, мы получаем нарушение принципа DRY. Представтье, что необходимо изменить расчёт зарплат. Вместо базовой части и компенсаторной, так же необходимо прибавить бонус. Для того, чтобы отразить это изменение в системе, нужно изменить оба метода. Если сделать это только для одного, мы получим разные расчёты в разных местах системы, что приводит нас к ошибке, в конечном счёте.

Генерация

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

Как процессы рушат DRY

Довольно часто в компаниях с крупными Java приложениями, используется связка следующих технологий:

  • Hibernate для организации работы приложения с базой данных и
  • Liquibase для управления миграциями структуры базы данных, посредством сохранения DDL выражений в специальных файлах

И Hibernate, и Liquibase управляют структурой базы данных. Если миграционный инструмент, позволяет явно прописывать структуру базы, используя SQL, то ORM инструмент, генерирует схему базы данных на основе её описания на языке программирования Java.

И вот процесс использования этой связки, в крупных компаниях обычно выглядит следующим образом:

  1. Программист пишет новый Entity класс или меняет существующий
  2. Затем, генерирует новую схему, используя специальные настройки Hibernate
  3. И после, “снимает” полученную в базе структуру, вручную, для того, чтобы скопировать результирующее DDL выражение в миграцию Liquibase

С точки зрения, адекватности подобного процесса - он абсолютно адекватен. Liquibase позволяет версионировать структуру базы данных, накатывать новые изменения и откатывать старые. Hibernate этого делать не умеет.

Но вот с точки зрения соблюдения принципа DRY, конечно же, это нарушение. Программист сначала изменяет структуру базы в Entity-классе, затем в liquibase-миграции. Два места, в которые нужно внести, фактически, одно и тоже изменение.

Как технологии помогают соблюдать DRY

Опять же, в крупных компаниях, работающих с микросервисами и событийно-ориентированным подходом, довольно часто, в качестве шины событий используется Kafka. И для Kafka есть технология, которая позволяет описывать схемы событий (далее event’ов) и их версионировать.

Как это работает? Программист, описывает схему event’а на специальном декларативном языке, а затем, во время сборки программной системы генератор, умеющий работать с подобными схемами, сам сгенерирует Java классы, для использования в программе.

В следующий раз, когда нужно будет поменять что-то в имеющейся схеме, программист изменит только саму схему. Генератор же, автоматически пересоздаст Java классы, относительно изменений в схеме.

Вот как принцип DRY может быть автоматически соблюдён при использовании определённых технологий.

Заключение

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

Полезные материалы

Больше о принципе DRY можно узнать здесь: