Ответ
DRY (Don't Repeat Yourself — «Не повторяйся») — это фундаментальный принцип разработки ПО, который гласит: «Каждое знание должно иметь единственное, непротиворечивое и авторитетное представление в системе».
На практике это означает устранение дублирования логики, а не просто текста кода. Два фрагмента кода считаются дублированием, если изменение одного из них по логической необходимости требует изменения другого.
Пример нарушения DRY:
public class OrderProcessor
{
public void Process(Order order)
{
// Дублирующаяся проверка и логирование
if (order.Items.Count == 0)
{
Logger.Log("Заказ пуст. Обработка отменена.");
return;
}
// Логика обработки...
}
public void Cancel(Order order)
{
// Та же самая проверка и логирование снова
if (order.Items.Count == 0)
{
Logger.Log("Заказ пуст. Отмена невозможна.");
return;
}
// Логика отмены...
}
}
Исправленный вариант (следование DRY):
public class OrderValidator
{
// Знание о валидации непустого заказа представлено в одном месте.
public static bool ValidateNotEmpty(Order order, string operationName)
{
if (order.Items.Count == 0)
{
Logger.Log($"Заказ пуст. Операция '{operationName}' отменена.");
return false;
}
return true;
}
}
public class OrderProcessor
{
public void Process(Order order)
{
if (!OrderValidator.ValidateNotEmpty(order, nameof(Process))) return;
// Логика обработки...
}
public void Cancel(Order order)
{
if (!OrderValidator.ValidateNotEmpty(order, nameof(Cancel))) return;
// Логика отмены...
}
}
Преимущества следования DRY:
- Снижение количества ошибок: Исправление или улучшение логики требуется только в одном месте.
- Упрощение поддержки: Код становится легче читать и изменять.
- Повышение согласованности: Поведение системы становится предсказуемым, так как одинаковая логика не разбросана по кодовой базе.
Важное уточнение: Не стоит абсолютизировать DRY на ранних этапах. Преждевременное абстрагирование дублирующегося кода, когда его назначение ещё не до конца ясно, может привести к созданию неправильных, жёстко связанных абстракций. Иногда лучше допустить контролируемое дублирование, чем создать плохую абстракцию.
Ответ 18+ 🔞
Ну вот смотри, этот ваш DRY, он же как в жизни — если одно и то же по десять раз на дню повторять, так и ебнуться недолго. Суть-то проще пареной репы: каждая фигня в твоём коде должна жить в одном-единственном месте, и точка.
Не в том дело, чтобы просто скопипастить строчки в функцию, а в том, чтобы знание — как эта штука работает — не было размазано по всей кодовой базе. Если меняешь логику в одном месте, а в другом забываешь — пиши пропало, будет тебе баг, как корове седло.
Смотри, как бывает, когда об этом принципе нихуя не думают:
public class OrderProcessor
{
public void Process(Order order)
{
// Вот эта проверка с логом...
if (order.Items.Count == 0)
{
Logger.Log("Заказ пуст. Обработка отменена.");
return;
}
// ...она же, блядь, через два метода...
}
public void Cancel(Order order)
{
// ...повторяется слово в слово! Чистой воды копипаста!
if (order.Items.Count == 0)
{
Logger.Log("Заказ пуст. Отмена невозможна.");
return;
}
// ...
}
}
Представь, заказчику взбрело в голову, что "пустой заказ" — это не когда ноль items, а когда общая сумма нулевая. Иди теперь ищи все эти order.Items.Count == 0 по всей программе, их же, наверное, дохуя! Обосрёшься, пока всё поправишь.
А вот как надо, по-человечески:
public class OrderValidator
{
// Всё! Знание о том, как проверить заказ на пустоту, живёт тут. В одном месте, блять.
public static bool ValidateNotEmpty(Order order, string operationName)
{
if (order.Items.Count == 0)
{
Logger.Log($"Заказ пуст. Операция '{operationName}' отменена.");
return false;
}
return true;
}
}
public class OrderProcessor
{
public void Process(Order order)
{
// Просто юзаем знание оттуда
if (!OrderValidator.ValidateNotEmpty(order, nameof(Process))) return;
// ...
}
public void Cancel(Order order)
{
// И тут юзаем. И везде оно одинаковое.
if (!OrderValidator.ValidateNotEmpty(order, nameof(Cancel))) return;
// ...
}
}
Теперь если заказчик ебёт мозг, меняешь логику в одном месте — в OrderValidator.ValidateNotEmpty. И всё, пиздец. Во всём приложении проверка сразу станет правильной. Красота!
Что это даёт, кроме спокойного сна?
- Меньше косяков: Поправил один раз — и везде применилось. Не будет ситуации "а тут исправил, а тут забыл".
- Легче ковыряться: Понимаешь, где что искать. Вся логика не раскидана, а сгруппирована.
- Всё стабильно: Система ведёт себя одинаково, потому что не может быть трёх разных реализаций одной и той же хуйни.
Но и тут есть подводный камень, ёпта! Не надо с этим принципом, как дурень с писаной торбой, носиться. Если видишь два похожих куска кода, но не уверен на все сто, что они всегда будут меняться вместе — не торопись их склеивать. Получится какая-нибудь монстрообразная функция с кучей if-ов, которую потом и сам не разберёшь. Иногда лучше пусть будет два простых, но понятных дубликата, чем одна "умная" хуйня, которая всех запутает. Сначала пойми, что к чему, а потом уже рефактори.