← Назад к вопросам

Что такое DRY?

1.0 Junior🔥 141 комментариев
#Архитектура и паттерны

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

DRY (Don't Repeat Yourself)

DRY — это один из основополагающих принципов разработки ПО, которая стремится минимизировать дублирование кода и логики. Впервые принцип был описан в книге "The Pragmatic Programmer" (1999) и с тех пор стал стандартом в индустрии.

Основная идея

Когда один и тот же блок кода, логика или информация повторяются в разных местах приложения, это создаёт:

  • Сложность поддержки — при изменении нужно обновлять везде
  • Риск ошибок — можно забыть обновить одно из мест
  • Неконсистентность — разные части могут работать по-разному
  • Снижение читаемости — больше кода = сложнее понять систему

Примеры нарушения DRY

// ❌ Плохо — дублирование валидации
function createUser(email: string) {
  if (!email.includes('@')) {
    throw new Error('Invalid email');
  }
  // логика создания
}

function updateUser(email: string) {
  if (!email.includes('@')) {
    throw new Error('Invalid email');
  }
  // логика обновления
}

function sendEmail(recipient: string) {
  if (!recipient.includes('@')) {
    throw new Error('Invalid email');
  }
  // логика отправки
}

Правильный подход

// ✅ Хорошо — валидация в одном месте
function validateEmail(email: string): boolean {
  return email.includes('@') && email.length > 5;
}

function createUser(email: string) {
  if (!validateEmail(email)) {
    throw new Error('Invalid email');
  }
  // логика создания
}

function updateUser(email: string) {
  if (!validateEmail(email)) {
    throw new Error('Invalid email');
  }
  // логика обновления
}

function sendEmail(recipient: string) {
  if (!validateEmail(recipient)) {
    throw new Error('Invalid email');
  }
  // логика отправки
}

Применение DRY в разных уровнях

Код и функции:

  • Выносим повторяющуюся логику в отдельные функции
  • Используем модули и библиотеки вместо копирования

Конфигурация:

  • Используем переменные окружения вместо хардкода
  • Централизуем настройки в одном файле
// ❌ Плохо
const dbUrl = 'postgres://localhost:5432/mydb';
const cacheUrl = 'redis://localhost:6379';

// ✅ Хорошо
const config = {
  database: {
    url: process.env.DATABASE_URL,
  },
  cache: {
    url: process.env.REDIS_URL,
  },
};

Данные и типы:

  • Используем типы и интерфейсы для определения структур один раз
  • Не повторяем типизацию в разных местах
// ✅ Хорошо — определяем тип один раз
interface User {
  id: string;
  email: string;
  name: string;
}

function getUser(id: string): User {
  // ...
}

function updateUser(id: string, user: Partial<User>): User {
  // ...
}

Стили и макеты:

  • Используем CSS классы вместо повторения inline стилей
  • Применяем utility-first подход (Tailwind CSS)

Границы DRY

Важно понимать, что DRY не абсолютен — иногда две похожие части кода лучше оставить отдельными, если:

  • Они могут развиваться независимо
  • Объединение добавит ненужную связанность
  • Код станет менее читаемым

Это называется "Нарушение DRY с целью" или применение принципа "YAGNI" (You Aren't Gonna Need It).

Инструменты и практики

  • Линтеры (ESLint, Ruff) находят потенциальное дублирование
  • Code Review — коллеги замечают копирование кода
  • Рефакторинг — регулярная чистка кода
  • Документация — единый источник истины для знаний

Итоги

DRY — это не просто красивый код, это: ✓ Меньше багов при изменениях ✓ Проще поддерживать проект ✓ Быстрее развиваться новым разработчикам ✓ Понятнее читать исходный код