Рефакторинг з низьким впливом та очищення неохайного коду під час очікування вимог


17

Я успадкував існуючу базу коду для продукту, який нібито неохайний. Фундаментальна конструкція надзвичайно неадекватна, що, на жаль, я не можу обійтися без повного рефактора (ВИСОКА зв'язок, низька когезія, невпинне копіювання коду, відсутність технічної проектної документації, інтеграційні тести замість одиничних тестів). Продукт має історію, високу схильність до критичних клієнтів «готівкою-коровою» з мінімальною толерантністю до ризику, технічну заборгованість, яка змусить греків червоніти, ДУЖЕ велику кодову базу та складність, а також бойовий підхід дефектистських підходів до помилок командою раніше я.

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

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

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

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

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


1
Пошкодьте те, що варто врятувати, решту перепишіть ...
С.Ф.

"Дуже рідко трапляються збої проекту технічної некомпетентності на відміну від відмови від управління проектами [...]" Наскільки це правда, +1.
Грегорі Хіглі

Відповіді:


22

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

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

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

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


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

10

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


2
Почніть з легких, потім працюйте вгору?
tdammers

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

2
Якщо код не був розроблений для тестів, це ще більше приводу для проведення тестів - але безпечно. Прочитати книгу Майкла Пір'я "Ефективна робота зі спадковим кодом"; у ньому є рецепти для того, щоб зробити нестійкий код перевіряючим.
Джо Вайт

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

1
Це вимагає певного досвіду та хороших оцінок. Не все можна (або слід) зробити одиничним для перевірки.
tdammers

1

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

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

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

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

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