DRY не пов'язаний, але майже ідентичний код


34

У мене є код, який майже ідентичний, але використовує абсолютно різні типи, без спадкування між ними, на головній змінній. Зокрема, я пишу аналізатор з Roslyn для C # та VB.NET із такими типами:

Microsoft.CodeAnalysis.CSharp.Syntax.AttributeSyntax Microsoft.CodeAnalysis.VisualBasic.Syntax.AttributeSyntax

Мені цікаво, якщо, оскільки код робить те саме, я повинен зберігати його як можна DRY, розбиваючи якомога менше на окремі (але ідентичні, крім типу) методи, або повністю розділяючи його, оскільки два способи є не пов'язані між собою і майбутні зміни можуть змусити одну версію змінити, а не іншу (хоча це малоймовірно)?

Редагувати: Рік чи пізніше я потрапив у цю саму проблему, і команда Рослін допомогла мені вирішити: Написати базовий клас, який бере загальну інформацію та має TAttributeSyntaxпараметр, який виконує більшу частину роботи. Потім запишіть похідні класи з мінімальним мінімумом даних, який потребує певного типу.


Чи вдасться створити власний інтерфейс AttributeSyntax, який охоплює існуючі класи, але дає вам спадщину, яка концептуально повинна бути там?
Вінстон Еверт

7
Вибачте, якщо це очевидно, але дженерики існують, тому вам не доведеться повторювати себе за кодом, який однаковий, але за типом. Якщо це не те, що ви мали на увазі, не враховуйте.
Девіслор

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

@WinstonEwert Я розгляну це. Я не впевнений, що хочу це зробити для всіх типів C # / VB.NET.
Hosch250

1
Рефакторинг накладає багато компромісів, а іноді навіть парадоксонів. Напр., Вільне з'єднання WRT проти DRY або короткі функції, але багато з них, порівняно з більш тривалими функціями, і їх мало. Зрештою, це важкий звір: Ваша мета - читабельність та ремонтопридатність. Вам потрібно мислити як аватар, який бачить ваш код вперше. І іноді ви просто намагаєтеся побачити, що краще. Ідеальний рефакторинг, на жаль, неможливий.
phresnel

Відповіді:


111

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

Зокрема з цього питання:

Якщо ви повторите себе, ви можете створити проблеми з ремонтом. Якщо doStuff1-3 усі мають аналогічний структурований код, і ви вирішите проблему в одному, ви можете легко забути виправити проблему в інших місцях. Крім того, якщо вам доведеться додати новий кейс для обробки, ви можете просто передавати різні параметри в одну функцію, а не склеювати копію всюди.

Однак DRY часто сприймають спритні програмісти. Іноді, щоб не повторювати себе, доводиться створювати абстракції настільки тупими, що ваші товариші по команді не можуть слідувати за ними. Іноді структура двох речей лише невиразно схожа, але досить різна. Якщо doStuff1-4 досить різні, так що перефактування їх, щоб вони не повторювались, змушує вас написати неприродний код або зазнати розумних зворотних кодувань, які змусять вашу команду відблискувати, тоді, можливо, буде добре повторити себе. Я схилився назад, щоб не повторити себе пару разів неприродними способами і пошкодував про кінцевий продукт.

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


Зважаючи на це, враховуючи SRP та просто намагаючись мати невеликі, гнучкі класи загалом, може бути доцільним проаналізувати свій код з цієї причини , розділити біти поведінки, які використовують загальні типи (ви сказали, що вони ідентичні, крім типу) на невеликі класи. Тоді ви дізнаєтесь, що деякі з цих класів насправді є абсолютно однаковими (не просто здебільшого однаковими), і тоді ви зможете скласти інструментарій на випадок, якщо хочете додати Microsoft.CodeAnalysis.CPlusPlus.Syntax.AttributeSyntax.


32
TL; DR - DRY - це засіб для досягнення мети. Орієнтуйтеся на кінець, а не на засоби. Якби я міг двічі виступити проти Лего-чоловіка, я б.

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