Нарушение принципа СУХОЙ

10

Я уверен, что где-то есть название для этого анти-паттерна; однако я не достаточно знаком с литературой по анти-шаблонам, чтобы знать это.

Рассмотрим следующий сценарий:

or0является функцией-членом в классе Что бы там ни было, это сильно зависит от переменных членов класса. Программист А приходит и нуждается в функциональности, такой как, or0но не вызов or0, Программист А копирует и переименовывает весь класс. Я предполагаю, что она не звонит, or0потому что, как я говорю, она сильно зависит от переменных-членов для ее функциональности. Или, может быть, она младший программист и не знает, как это вызвать из другого кода. Так что теперь у нас есть or0и c0(с для копирования). Я не могу полностью обвинить Программиста А в этом подходе - мы все попали в сжатые сроки и взломали код, чтобы выполнить работу.

Несколько программистов поддерживают, or0так что теперь это версия orN. c0сейчас версия cN. К сожалению, большинство программистов, которые поддерживали содержание класса, or0казалось, совершенно не знают c0- что является одним из самых сильных аргументов, которые я могу придумать для мудрости принципа СУХОЙ. И, возможно, также было независимое ведение кода в c. В любом случае кажется, что or0и c0были поддержаны независимо друг от друга. И, радость и счастье, ошибка происходит в cNтом, что не происходит в orN.

Итак, у меня есть несколько вопросов:

1.) Есть ли название для этого анти-паттерна? Я видел, как это происходит так часто, что мне трудно поверить, что это не названный анти-паттерн.

2.) Я вижу несколько альтернатив:

a.) Исправлена ​​ошибка, orNпри которой принимался параметр, определяющий значения всех необходимых ему переменных-членов. Затем измените cNвызов так, чтобы orNвсе необходимые параметры были переданы.

б.) Попробуйте вручную перенести исправления из orNв cN. (Имейте в виду, я не хочу этого делать, но это реалистичная возможность.)

c.) Переписать, orNчтобы - cNснова, чёрт, но я перечислю это для полноты картины.

г.) ​​Попытайтесь выяснить, где cNсломан, а затем отремонтировать его независимо от orN.

Альтернатива кажется лучшим исправлением в долгосрочной перспективе , но я сомневаюсь , что клиент позволит мне реализовать. Никогда не время и деньги, чтобы исправить все правильно, но всегда время и деньги, чтобы решить ту же проблему 40 или 50 раз, верно?

Кто-нибудь может предложить другие подходы, которые я, возможно, не рассмотрел?

Онорио Катеначчи
источник
"Есть ли название для этого анти-паттерна?" «Нарушающий сухой» анти-паттерн? :) ИМХО ты в значительной степени сам на это ответил.
Стивен Джеурис
Может быть, назвать это «Сухой нарушитель»?
FrustratedWithFormsDesigner
2
Я называю это: СУХОЙ натыкаясь.
AJC
5
Копировать и вставить кодирование?
Tylermac
Это называется «слишком много поваров портят бульон».
Док Браун

Ответы:

18
  1. это просто называется дубликат кода - я не знаю более причудливых имен для этого. Долгосрочные последствия, как вы описали, и хуже.

  2. Конечно, устранение дублирования является идеальным вариантом, если это возможно. Это может занять много времени (в недавнем случае в нашем унаследованном проекте у меня было несколько методов, дублированных на более чем 20 подклассов в иерархии классов, многие из которых эволюционно увеличили свои незначительные различия / расширения за эти годы. мне около 1,5 лет, благодаря написанию последовательных юнит-тестов и рефакторингу, чтобы избавиться от всех дубликатов. Упорство стоило того, хотя).

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

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

Петер Тёрёк
источник
3
+1, если не только за упоминание дубликата кода, но и за огромные усилия, приложенные к вашей истории рефакторинга кода. : D
Андреас Йоханссон
9

Существует ссылка на шаблон « WET» («Нам нравится печатать»), но я не знаю, является ли это стандартным именем.

... Лицензирование программного обеспечения является заметным исключением из практики DRY (не повторяйте себя) - код лицензирования программного обеспечения должен быть максимально влажным (нам нравится печатать - противоположность DRY).

Если вы изолируете свою логику лицензирования в одном месте, отделенную от других проблем, вы значительно упростите модификацию своего программного обеспечения, чтобы полностью отключить лицензирование. Гораздо лучше повторять лицензионную логику много раз по всему приложению, предпочтительно так, чтобы она выполнялась много раз за одно выполнение программного обеспечения.

Например, мы предлагаем вам выполнить проверку лицензирования во время установки, во время запуска приложения и при каждом доступе к важным функциям. Не проверяйте лицензию один раз во время запуска и не передавайте это значение; вместо этого, фактически скопируйте проверку лицензирования в каждой области. Это неудобно, но гораздо лучше, чем выпускать продукт, который легко взломать ...

Jeremy-джордж
источник
3
WET может означать: писать все дважды
StuperUser
1
@StuperUser Я обнаружил, что вчера на dailywtf ...
Джереми-Джордж
3

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

Вам также следует ознакомиться с модификаторами доступности. Убедитесь, что те вещи, которые являются публичными, на самом деле должны быть публичными. Потребителю не нужно знать о каждом маленьком члене ... использовать инкапсуляцию.

Это требует рефакторинга. Также кажется, что код пишется без предварительного дизайна. Посмотрите на разработку через тестирование. Напишите код так, как он должен называться, а не вызывайте код, каким бы он ни был реализован. Посмотрите в TDD несколько советов о том, как выполнить задачу.

P.Brian.Mackey
источник
3

Если вы копируете код, вы вводите технический долг двойного обслуживания или, более конкретно, дублирование кода .

Обычно это исправляется с помощью рефакторинга. Более конкретно, вы перенаправляете все вызовы на новую функцию (или новый метод в новом классе), которая имеет общий код. Самый простой способ начать - это удалить весь скопированный код и посмотреть, что ломается, в котором вы исправляете, перенаправляя вызовы к общему коду.

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

Spoike
источник
1

Звучит как код спагетти для меня. Лучшее решение - это рефакторинг / перезапись.

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

http://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Spaghetti.jpg/175px-Spaghetti.jpg

Том Сквайрс
источник
-1 Refactor и rewrite - два очень разных варианта. Тотальное переписывание, выбрасывание программного обеспечения, никогда не было хорошей идеей. joelonsoftware.com/articles/fog0000000069.html
P.Brian.Mackey
1
Код спагетти - это IMO гораздо более общий и более свободный термин. Хотя такой код часто содержит дубликаты, вы можете иметь спагетти-код без дублирования, а также сильно дублированный, но не спагетти-код.
Петер Тёрёк
@ P.Brian.Mackey Я никогда не говорил, что Refactor и rewrite - это одно и то же. ОП должен решить, какой использовать.
Том Сквайрс
2
Я никогда не был поклонником этой статьи. Я согласен, что переписывание было плохой идеей в приведенном примере, но только потому, что в этом случае это была плохая идея, не означает, что это всегда плохая идея. Для начала, сделает ли блок перезаписи какой-либо другой прогресс? Если так, то это плохо; если нет, то это не так плохо.
Джоккинг
@jhocking - Я считаю, что политика недопущения переписывания заключается не в том, чтобы блокировать прогресс в других программах, а в том, что со временем происходит потеря реальных исправлений. Это волшебное «if (goldenNugget> 22)», хотя оно и плохо названо, по-прежнему решает конкретную проблему, которую вполне может быть невозможно определить без часов или дней исследований. Теперь, взяв те же данные и улучшив их, это то, что должно быть сделано вместо этого. Это рефакторинг. Выбросить его и сказать «мы сделаем это правильно в следующий раз» - пустая трата времени. По той же причине решение уже решенных проблем - пустая трата времени. Добавление хорошего кода поверх плохого увеличивает долг
P.Brian.Mackey
0

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

Если вы когда-нибудь думали, что вам нужно создать ужасный код, чтобы уложиться в сроки, то запросом абсолютного наивысшего приоритета для релиза после этого должно быть исправление ужасного кода СЕЙЧАС. Так что ваша проблема ушла.

СУХОЙ принцип - для ситуаций, которые не совсем совершенны и могут быть улучшены. Дублирование класса - это совершенно новый калибр. Сначала я бы назвал это «дублированный код», и со временем он изменится на худшую из всех «трата времени», «расходящийся дублированный код»: несколько копий одного и того же кода, которые почти, но не совсем идентичны, и никто не знает, Различия предназначены, совпадения или ошибки.

gnasher729
источник
-3

Почти на десять лет опоздал на эту вечеринку, но название этого анти-паттерна называется Divergent Change , где несколько классов содержат копии одного и того же поведения, но с течением времени и технического обслуживания, а некоторые классы забываются, эти поведения расходятся.

В зависимости от того, что такое общее поведение и как его разделяют, его можно было бы назвать « Хирургия с дробовиком» , с той лишь разницей, что здесь одна логическая функция предоставляется многими классами, а не одним.

doOOooonkeyKoooOOOooong
источник
1
Это не похоже на то же самое. Дивергентное изменение - это когда много изменений вносятся в один класс. ОП описывает дублирование кода. Хирургия дробовика тоже не одно и то же. Shotgun Surgery описывает одно и то же изменение, внесенное в несколько разных классов.
Роберт Харви