Принцип DRY заставляет думать о переиспользуемых компонентах и выносить общее поведение в одно место. Копии кода приходится искать, менять и тестировать отдельно. Но бездумное устранение любого повторения тоже портит систему.
Одинаковый код может иметь разную судьбу
DRY хорошо работает для утилитарных вещей вроде логирования. С бизнес-логикой всё менее однозначно.
Мне неоднократно приходилось распиливать «универсальный» код, продираясь через сложные абстракции и нечитаемые дженерики. Желание переиспользовать всё сразу создаёт компонент с высокой связанностью. Через него начинают зависеть друг от друга части системы, которые должны развиваться независимо.
Поэтому, когда два фрагмента бизнес-логики хочется схлопнуть в общий модуль, я задаю себе один вопрос:
Будет ли этот код развиваться по-разному?
Одинаковые сегодня сценарии через несколько месяцев могут разъехаться из-за разных бизнес-требований. Тогда универсальный компонент обрастает флагами, параметрами и исключениями, а любое изменение требует проверять всех потребителей.
Универсального рецепта нет. Иногда лучше оставить две или три копии и дать им развиваться независимо. Десять копий оставлять не надо, всему есть предел.