Порушення принципу DRY


10

Я впевнений, що десь є назва цього анти-шаблону; однак я недостатньо знайомий з літературою проти зразків, щоб це знати.

Розглянемо наступний сценарій:

or0- це членська функція в класі. На краще чи гірше, це сильно залежить від змінних членів класу. Програміст A приходить і потребує функціональності, or0а не викликає or0, програміст A копіює та перейменовує весь клас. Я здогадуюсь, що вона не дзвонить, or0тому що, як я кажу, вона сильно залежить від змінних членів для її функціональності. А може, вона молодший програміст і не знає, як це викликати з іншого коду. Отже, тепер у нас є or0і c0(c для копії). Я не можу повністю винувати програміста А в такому підході - всі ми дотримуємося строгих термінів, і ми зламаємо код, щоб завершити роботу.

Кілька програмістів підтримують, or0тож тепер це версія orN. c0зараз версія cN. На жаль, більшість програмістів, які підтримували клас, що містив, or0здавалося, абсолютно не знають про c0це, - що є одним із найсильніших аргументів, про які я можу подумати про розумність принципу DRY. І, можливо, також було незалежне підтримання коду в c. У будь-якому випадку є , що or0і c0підтримували незалежно один від одного. І, радість і щастя, відбувається помилка в cNтому, що не відбувається в orN.

Тож у мене є кілька питань:

1.) Чи існує назва цього анти-шаблону? Я бачив, як це трапляється так часто, мені важко повірити, що це не названий анти-шаблон.

2.) Я бачу кілька альтернатив:

a.) Виправити orNприйняття параметра, який визначає значення всіх змінних членів, які йому потрібні. Потім змініть cNвиклик orNз усіма необхідними параметрами, переданими в.

b.) Спробуйте вручну виправити поправки з orNдо cN. (Зверніть увагу, я не хочу цього робити, але це реальна можливість.)

в.) Відновлюйся orN- cNповертайся, поцупи, але я перераховую це заради повноти.

г.) ​​Спробуйте розібратися, де cNзламана, а потім відремонтуйте її незалежно від orN.

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

Чи може хтось запропонувати інші підходи, які я, можливо, не розглядав?


"Чи існує назва цього анти-шаблону?" "Порушувальний-сухий" анти-візерунок? :) IMHO, ви майже самі відповіли на це.
Стівен Євріс

Може назвати це "Сухий порушник"?
FrustratedWithFormsDesigner

2
Я називаю це: ДУХИЙ нахил.
AJC

5
Скопіювати та вставити кодування?
tylermac

Його називають схемою "занадто багато кухарів псують бульйон".
Doc Brown

Відповіді:


18
  1. його просто називають дублікатом коду - я не знаю більше фантазійних імен для цього. Довгострокові наслідки такі, як ви описали, і гірші.

  2. Звичайно, усунення дублювання є ідеальним варіантом, якщо це можливо. Це може зайняти багато часу (в недавньому випадку в нашому сталому проекті у мене було декілька методів, дублюваних понад 20 підкласів в ієрархії класів, багато з яких еволюційно виросли свої власні незначні відмінності / розширення протягом багатьох років. Це зайняло мені близько 1,5 років через послідовне написання тестових підрозділів та рефакторинг, щоб позбутися від усіх дублювань. Хоча наполегливість того вартувала).

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

    Багато невеликих удосконалень можуть призвести до великої зміни в довгостроковій перспективі. Вам не обов’язково потрібне чітке схвалення клієнта на це - трохи рефакторингу кожного разу, коли ви торкаєтесь зазначеного класу, щоб виправити помилку чи реалізувати функцію, може пройти довгий шлях з часом. Просто включіть додатковий час для рефакторингу у ваші кошторисні завдання. Це як звичайне технічне обслуговування, щоб підтримувати програмне забезпечення здоровим у довгостроковій перспективі.


3
+1, якщо не тільки згадування дублюючого коду, але й зусилля, які були залучені до вашої історії про перетворення коду. : D
Андреас Йоханссон

9

Є посилання на модель WET (Ми насолоджуємось друкуванням), але я не знаю, чи це стандартна назва.

... Ліцензування програмного забезпечення є помітним винятком із практики сухих (не повторюйте себе) - код ліцензування програмного забезпечення повинен бути максимально МОТИМ (ми насолоджуємось введенням тексту - навпаки DRY).

Якщо ви виділите свою ліцензійну логіку в одне місце, відокремлене від інших проблем, ви набагато простіше змінити програмне забезпечення, щоб повністю відключити ліцензування. Набагато краще повторювати логіку ліцензування багато разів протягом усієї програми, бажано, щоб вона виконувалася багато разів протягом одного виконання програмного забезпечення.

Наприклад, ми пропонуємо вам здійснити перевірку ліцензування під час встановлення, під час запуску програми та кожного разу, коли доступні важливі функції. Не перевіряйте ліцензію один раз під час запуску та передайте це значення навколо; натомість фактично копіювати перевірку ліцензування у кожній області. Це незручно, але набагато краще, ніж випускати продукт, який легко зламати ...


3
WET може означати: Пишіть все двічі
StuperUser

1
@StuperUser Я виявив, що на dailywtf вчора ...
jeremy-george

3

Якщо я вас правильно зрозумів, у класі відбувається занадто багато. Це створює методи, які не відповідають принципу єдиної відповідальності . Ведучий до коду, який потрібно переміщувати, шматки, зняті, а інші залишилися. Це також може створити багато членів.

Також слід переглянути модифікатори доступності. Забезпечте те, що є загальнодоступним, насправді має бути публічним. Споживачеві не потрібно знати про кожного маленького члена ... використовувати інкапсуляцію.

Це вимагає рефактора. Здається також, що код пишеться без попереднього дизайну. Подивіться на розробку тестових програм. Напишіть код, як його слід викликати, а не називати код, однак він реалізований. Подивіться в TDD для підказки, як виконати завдання.


3

Якщо ви копіюєте код, ви введете технічну заборгованість за подвійне обслуговування або, точніше, - дублювання коду .

Зазвичай це фіксується за допомогою рефакторингу. Більш конкретно, ви переспрямовуєте всі виклики на нову функцію (або новий метод у новому класі), що має загальний код. Найпростіший спосіб почати - видалити весь скопійований код і побачити, що порушується, і що ви виправляєте, перенаправляючи виклики до загального коду.

Змусити свого клієнта погодитися на код рефактора може бути важким, оскільки важко переконати нетехнічну особу виправити технічну заборгованість. Тож наступного разу, коли ви дасте кошторис часу, просто включіть час, необхідний для рефакторації, до своїх оцінок . Більшість випадків клієнти вважають, що ви чистите код під час виправлення.


1

Мені звучить код спагетті . Найкраще виправлення - це рефактор / переписати.

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

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


-1 Рефактор і перезапис - це два дуже різні варіанти. Усього переписує, відкидаючи програмне забезпечення, ніколи не є доброю ідеєю. joelonsoftware.com/articles/fog0000000069.html
P.Brian.Mackey

1
Код спагетті - ІМО набагато більш загальний - і слабкіший - термін. Хоча такий код часто містить дублювання, ви можете мати код спагетті без будь-якого дублювання, а також сильно дублюється, але не код спагетті.
Péter Török

@ P.Brian.Mackey Я ніколи не говорив, що Refactor і переписати - це одне і те ж. ОП має вирішити, що використовувати.
Tom Squires

2
Я ніколи не був шанувальником цієї статті. Я згоден, що переписання було поганою ідеєю в наведеному прикладі, але те, що це погана ідея в цьому випадку, не означає, що це завжди погана ідея. Для початку, чи буде перезапис блокувати будь-який інший прогрес? Якщо так, це погано; якщо ні, то це ще не так вже й погано.
поштовх

@jhocking - Я вважаю, що суть політики без перезапису полягає не в тому, щоб блокувати прогрес в інших програмах, а в втраті реальних виправлень з часом. Це магічне "if (goldenNugget> 22)", хоча воно іменується погано, все ж вирішує конкретну проблему, яку цілком неможливо визначити без годин чи днів досліджень. Тепер, беручи ці самі дані та вдосконалюючи їх, це те, що слід зробити замість цього. Це рефактор. Викинути це і сказати, що «ми зробимо це наступного разу» - це марна трата часу. Ця ж причина вирішення вже вирішених проблем - це марна трата часу. Додавання хорошого коду поверх поганого збільшує заборгованість
P.Brian.Mackey

0

Ви кажете, що не можете повністю звинуватити A - але скопіювати клас таким чином насправді непростимо. Це масовий збій у процесі перегляду коду. Це, можливо, наймасштабніший збій, який взагалі не має огляду коду.

Якщо ви коли-небудь думаєте, що вам потрібно створити жахливий код, щоб дотриматись терміну, то абсолютним найвищим пріоритетним запитом на випуск після цього повинен бути виправити жахливий код ЗАРАЗ. Тож ваша проблема пішла.

Принцип DRY призначений для ситуацій, які не зовсім ідеальні і можуть бути вдосконалені. Дублювання класу - це зовсім новий калібр. Спершу я б назвав це "дублюючим кодом", і з часом він зміниться на найгірші за всі часи споживачі, "розбіжний дублюваний код": кілька копій одного і того ж коду, які майже, але не зовсім однакові, і ніхто не знає, чи розбіжності призначені, збіг чи помилки.


-3

Майже на десятиліття спізнюється ця партія, але назва цього анти-шаблону - Дивергентна зміна , де кілька класів включають копії однієї поведінки, але оскільки час і прогрес у обслуговуванні та деякі класи забуваються, ці форми поведінки розходяться.

Залежно від того, що таке спільна поведінка та як вона поділяється, її замість можна назвати Shotgun Surgery , різниця полягає в тому, що тут одна логічна особливість надається багатьма класами, а не одним.


1
Це не схоже на те саме. Розбіжна зміна - це коли багато змін внесені до одного класу. ОП описує дублювання коду. Стрілецька хірургія теж не одне і те ж. Shotgun Surgery описує однакові зміни, внесені до декількох різних класів.
Роберт Харві
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.