TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.74K subscribers
Post #3221 1.63K
День 2691. #ЗаметкиНаПолях
DRY — Самый Неправильно Понимаемый Принцип Программирования

Разработчики рано усваивают принцип DRY, и почти все - неправильно. Видишь два одинаковых фрагмента кода, выдели метод, удали дубликат. Такая практика может привести к очень плохому коду:
- Вспомогательный метод, в который каждый спринт добавляется новый логический параметр.
- Базовый класс, к которому никто не хочет прикасаться, т.к. от него наследуются шесть других несвязанных между собой.
- «Общий» модуль, от которого зависят две разные части системы, поэтому ни одна из них не может измениться без другой.
Каждый случай начинался как невинная попытка не повторяться.

Что на самом деле говорит DRY
Оригинальное определение из книги «Программист-прагматик»: «Каждое знание должно иметь единственное, однозначное, авторитетное представление в системе.»
Речь о знаниях, а не о коде. Один факт о предметной области (правило скидки или формат номера счёта), должен храниться ровно в одном месте. Когда факт меняется, вы меняете его в одном месте.

Ошибка: Дедупликация кода, а не знаний
Два фрагмента кода могут выглядеть идентично, но представлять совершенно разные знания. Допустим, вы проверяете два адреса: адрес доставки клиента и адрес склада. Сегодня правила идентичны:
public bool IsValid(Address addr) =>
!string.IsNullOrWhiteSpace(addr.Street) &&
!string.IsNullOrWhiteSpace(addr.City) &&
…

DRY призывает выделить один валидатор и вызывать его из обоих мест. Но это разные концепции, которые пока(!) имеют общие правила. Когда складу понадобится номер погрузочных ворот, вы вернётесь в общий метод и добавите флаг, чтобы другой вызывающий код продолжал работать:
public bool IsValid(Address addr, bool hasDock = false) =>
!string.IsNullOrWhiteSpace(addr.Street) &&
…
(!hasDock || !string.IsNullOrWhiteSpace(addr.DockCode));

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

Границы модулей
Внутри одного класса плохой вспомогательный метод раздражает. Общий код, переходящий через границы модулей это уже структурный ущерб. Представьте модульный монолит с модулями счетов и доставки. В обоих есть класс заказа. Инженер с благими намерениями замечает, что классы имеют общие поля, и объединяет их в один, на который ссылаются оба модуля:
public class Order
{
public Guid Id { get; set; }
public string CustomerName { get; set; }
public decimal Total { get; set; }
// … другие поля из обоих модулей
}

Теперь модули не могут развиваться независимо. Два модуля, каждый из которых имеет собственный класс заказа, — суть хранения данных в их границах. Формы могут быть похожими, моделируя одну и ту же реальную вещь с двух точек зрения, которые меняются со временем.

Правило: Дождитесь третьего раза
Не рефакторьте первый повтор. Дождитесь третьего раза и спросите себя: если это правило изменится, должны ли все копии так же измениться?
Да — это дублирование, примените DRY. Нет — это совпадение, оставьте как есть, объединение обойдётся вам дороже позже.

Пусть код повторяется до тех пор, пока правильная абстракция не станет очевидной, потому что хорошие абстракции обнаруживаются на конкретных примерах, а не угадываются заранее. Некоторые называют это AHA (Avoid Hasty Abstractions - Избегайте поспешных абстракций).

Извлекайте информацию, когда можете дать название концепции. Реальное доменное имя: Money, TaxRate или InvoiceNumber - вероятно, представляет собой общее знание. Если лучшее имя, которое вы можете найти, — Helper, Utils или ProcessData, вы абстрагируете форму, а не знания.

Источник: https://www.milanjovanovic.tech/blog/dry-is-the-most-misunderstood-rule-in-programming
  • 👍 24
  • 👎 1
More from @netdeveloperdiary
  1. Sep 26, 2026День 2796. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Продолжение Начало Три…
  2. Sep 25, 2026День 2795. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Начало Проблема с позиц…
  3. Sep 24, 2026День 2794. #Оффтоп #Здоровье Сегодня будет необычный пост. Завтра в Москве стартует конфер…
  4. Sep 23, 2026День 2793. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Ч…
  5. Sep 22, 2026День 2792. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Ч…
  6. Sep 21, 2026🔍Тестовое собеседование с Senior C# разработчиком уже завтра 22 сентября(уже завтра!) в 1…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →