Чи слід рефакторировать код, позначений як "не змінювати"?


148

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

Під час рефакторингу час від часу я стикаюся з класом, методом або рядками коду, які мають такі коментарі

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

або

Не змінюйте цього. Повірте, ви зламаєте речі.

або

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

Моє запитання: чи слід переробляти код, коли я стикаюся з подібними попередженнями авторів (ні, я не можу зв’язатися з авторами)?


157
Вітаємо! Тепер ви автор коду.

12
Ви не можете його виправити, поки не дізнаєтеся, що він повинен робити, і що він насправді робить (потрібно знати останнє, щоб зрозуміти всі наслідки змін). Проблема, як видається, полягає в синхронізації та усуненні таких проблем. повинно бути рефакторинг №1, інакше з кожною зміною все просто погіршиться. Питання, яке вам слід задавати, - це зробити. У цьому питанні існує досить велика залежність від мови та платформи. наприклад: stackoverflow.com/questions/3099794/finding-threading-bugs
sdenham

14
Слідкуйте за коментарем @ sdenham: якщо у вас ще немає автоматизованих тестових одиниць, які здійснюють базу коду, я пропоную витратити свій час на створення таких тестових одиниць, а не витрачати час на "рефакторинг полювання на відьом" з AFAICT без чітких цілей в пам'яті. Після того, як у вас буде набір одиничних тестів, які досконало здійснюють базу коду, ви матимете об'єктивний спосіб дізнатися, чи працює ваш код, якщо / коли вам доведеться переписати його біти. Удачі.
Боб Джарвіс

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

7
@Ethan Це може бути не так просто. Зміна коду може порушити його способами, які не відразу видно. Іноді це зламається довго після того, як ви забули, що цей теперішній рефактор міг це спричинити, тому все, що у вас є, - це "нова" помилка з загадковою причиною. Це особливо ймовірно, коли це пов'язано з термінами.
Пол Брінклі

Відповіді:


225

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

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

Ось краща стратегія: використовуйте свій час

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

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

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

  • отримати копію книги Пера "Ефективна робота зі застарілим кодом" для команди.

Отже, коли настане час, коли ви точно знаєте, що вам потрібно змінити та змінити крихкі модулі (або через розробку нової функції, або через тести, які ви додали на кроці 1, виявляєте деякі помилки), тоді ви та ваша команда готові refactor модулі і більш-менш безпечно ігнорувати ці застереження.

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


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

98
Я можу стверджувати, що будь-який код, позначений коментарем "Час вичерпано, щоб дати модулю A деякий час, щоб зробити речі. Якщо його не приурочено до цього, він зламається" вже є помилка. Це просто удача, що помилка не потрапляє.
17 з 26

10
@ 17of26: не обов’язково помилка. Іноді, працюючи з сторонніми бібліотеками, ви змушуєтесь робити усілякі «елегантні» поступки, щоб змусити його працювати.
whatsisname

30
@ 17of26: якщо в модулі на кону підозрюються помилки, додавання тестів перед рефакторингом ще важливіше. І коли в цих тестах виявляється помилка, тоді у вас виникає потреба змінити цей модуль, і таким чином легітимація негайно його рефактор. Якщо тести не виявляють помилок, краще залиште код таким, який він є.
Doc Brown

17
@Aaron: Я не розумію, чому ви вважаєте, що додавання тестів чи дотримання принципу хлопчиків-скаутів, отже, знизить якість продукції.
Doc Brown

142

Так, слід перефактурувати код, перш ніж додавати інші функції.

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

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

У вашому випадку ви не знаєте оригінальних обставин, а також не можете запитати оригінальних авторів. (Імовірно, ви також не маєте належного тесту на регресію / інтеграцію, або ви можете просто продовжити і нехай ваші тести підкажуть, чи щось ви зламали.)

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


46
Найкраща відповідь прямо тут; занадто погано, що це недоїдач. Прийнята вище відповідь не є гарною порадою, особливо наголосом на "приреченому". Я провів останній рік, працюючи над найбільшим (~ 10 ^ 6LOC тільки для мого розділу), спадщиною, чудовим кодом, який я коли-небудь бачив, і я встигаю виправляти аварії поїздів, які я бачу, коли маю час, навіть якщо це не частина компонента, над яким я працюю. Роблячи це, я виявив і виправив помилки, про які команда розробників навіть не знала, що існували (хоча, напевно, були наші кінцеві користувачі). Насправді мені доручено. В результаті поліпшується продукт.
Аарон

10
Я б не називав це рефакторинг, але помилку виправлення.
Paŭlo Ebermann

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

10
@Aaron вам пощастило мати підтримку управління / розробника. У більшості середовищ відомі та невідомі помилки, спричинені поганим дизайном та кодом, приймаються як природний порядок речей.
Рудольф Олах

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

61

Моє запитання: чи слід переробляти код, коли я стикаюся з подібними попередженнями авторів

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

поки що ми більше не можемо додати жодної функції, не порушивши щось інше

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

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

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

Кожен раз, коли ви виправляєте помилку, додайте тестовий випадок, який підтверджує, що помилка виправлена. Це запобігає прямим регресіям.

Коли ви додаєте нову функцію, додайте принаймні деякі основні тестування, щоб нова функція працювала за призначенням.

Можливо, отримаєте копію "Ефективної роботи зі спадковим кодом"?

Мені дали кілька місяців на рефакторинг існуючого коду.

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

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


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

2
Правильно. Або якщо немає спеціальної перевірки специфіки, чи потрібна попередня поведінка людям, які платять за або мають інтерес до програмного забезпечення.
bdsl

Можливо, отримаєте копію "Ефективної роботи зі спадковим кодом"? Скільки тижнів знадобиться йому, щоб прочитати цю книгу? А коли: у робочий час на робочому місці, вночі, коли всі сплять?
Біллал Бегерадж

23

Пам’ятайте про огорожу Г. К. Честертона : не знімайте паркан, що перешкоджає дорозі, поки не зрозумієте, чому він був побудований.

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

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

До цього я не торкався коду, який позначений "не чіпай".


4
ОП каже: «ні, я не можу зв’язатися з авторами».
FrustratedWithFormsDesigner

5
Я не можу зв’язатися з авторами, ні документації.
kukis

21
@kukis: Ви не можете зв’язатися з авторами, будь-якими експертами з домену та не можете знайти будь-які електронні листи / вікі / документи / тестові випадки, що стосуються коду, про який йдеться? Ну, тоді це повноцінний дослідницький проект в археології програмного забезпечення, а не просте завдання рефакторингу.
9000

12
Незвично, що код старий і автори пішли. Якщо вони закінчили працювати для конкурента, то обговорення цього може порушити чиїсь NDA. У кількох випадках автори постійно недоступні: ви не можете запитати Філа Каца про ПКзіпа, оскільки він помер роки тому.
pjc50

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

6

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

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

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

Отже, у випадку тайм-ауту: Залиште його, поки ви точно не зрозумієте, що чекає код, а потім виправте причину введення тайм-ауту, перш ніж приступати до його видалення.

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


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

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

5

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

Але якщо вам потрібно рефактор ...

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


5

Я кажу, ідіть і змініть це. Вірите чи ні, не кожен кодер є генієм, і подібне попередження означає, що це може бути місцем для вдосконалення. Якщо ви виявите, що автор мав рацію, ви можете (задихатися) ДОКУМЕНТ або пояснити причину попередження.


4

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

На даний момент питання про те, чи потрібно робити рефактор, є передчасним (навіть якщо він, мабуть, відповість конкретною формою "так").

Основне питання тут полягає в тому, що (як зазначається в деяких відповідях) коментарі, які ви цитуєте, рішуче вказують на те, що код має змагальні умови або інші проблеми одночасності / синхронізації, про які йдеться тут . Це особливо складні проблеми з кількох причин. По-перше, як ви виявили, начебто непов'язані зміни можуть викликати проблему (інші помилки також можуть мати такий ефект, але помилки паралельності майже завжди роблять.) По-друге, їх дуже важко діагностувати: помилка часто виявляється в місці, яке є віддалений у часі чи код від причини, і все, що ви зробите для діагностики, може призвести до його відходу ( Heisenbugs). По-третє, помилок одночасності дуже важко знайти при тестуванні. Частково це відбувається через комбінаторний вибух: він досить поганий для послідовного коду, але додавання можливих переплетень одночасного виконання підриває його аж до того, що послідовна проблема стає незначною у порівнянні. Крім того, навіть хороший тестовий випадок може викликати проблему лише зрідка - Ненсі Левесон підрахувала, що один із смертельних помилок у Therac 25відбулося за 1 з приблизно 350 пробіжок, але якщо ви не знаєте, що таке помилка, або навіть, що вона є, ви не знаєте, скільки повторень робить ефективний тест. Крім того, лише автоматизоване тестування є можливим у такому масштабі, і можливо, що тест-драйвер накладає тонкі обмеження в часовому режимі, щоб він ніколи насправді не викликав помилку (знову Heisenbugs).

Існують деякі інструменти для тестування на сумісність у деяких середовищах, наприклад, Helgrind для коду, що використовує pthreads POSIX, але тут ми не знаємо специфіки. Тестування слід доповнити статичним аналізом (чи це навпаки?), Якщо є відповідні інструменти для вашого оточення.

Щоб додати труднощі, компілятори (і навіть процесори під час виконання) часто вільні реорганізувати код способами, які іноді роблять міркування щодо його безпеки потоків дуже протиінтуїтивними (можливо, найвідоміший випадок - це двічі перевірена ідіома блокування , хоча деякі середовища (Java, C ++ ...) були змінені, щоб покращити її.)

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


1
Де ви бачите "стан перегонів" у коментарях? Де це навіть мається на увазі? Ви робите надзвичайно багато технічних припущень, навіть не бачачи коду.
Роберт Харві

2
@RobertHarvey "Час вичерпано, щоб дати Модулю деякий час, щоб зробити речі". - в значній мірі визначення стану гонки, і тайм-аути - це не найрізноманітніший спосіб їх вирішення. Я не єдиний, хто зробив цей висновок. Якщо тут немає проблем, це добре, але запитуючий повинен знати, враховуючи, що ці коментарі є червоними прапорами для погано керованої синхронізації.
sdenham

3

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

Під час рефакторингу час від часу я стикаюся з класом, методом чи рядками коду, які містять коментарі на зразок ["не торкайся цього!"]

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

Дізнайтеся, що роблять ці складні модулі, і розбийте їх на менші проблеми (що мали зробити оригінали авторів). Щоб уникнути безладного коду з безладу, хороші частини потрібно відремонтувати, а погані - потрібно переписати .


2

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

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

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

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

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

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


1

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

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

В ідеалі ви зможете зрозуміти, в чому проблема, і правильно її виправити. Наприклад:

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

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

Не змінюйте цього. Повірте, ви зламаєте речі.

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

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

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

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

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


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

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

1
@supercat Можливо, може, й ні. Ми не можемо сказати з коментаря тут. Тож варто дослідити, щоб, якщо нічого іншого, покращити коментар із специфікою.
Девід Шварц

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

1

Автор коментарів, швидше за все, сам не повністю зрозумів код . Якби вони насправді знали, що роблять, вони написали б фактично корисні коментарі (чи не ввели б гоночні умови в першу чергу). Коментар на кшталт " Повір мені, ти зламаєш речі ". Для мене вказується, що автор намагається змінити щось, що спричинило несподівані помилки, які вони не повністю зрозуміли.

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

Це означає:

  1. Зміна коду ризиковано. Очевидно, знадобиться час, щоб зрозуміти, і це, мабуть, не відповідає хорошим принципам дизайну і може мати незрозумілі наслідки та залежності. Він, швидше за все, недостатньо перевірений, і якщо ніхто повністю не розуміє, що робить код, буде складно написати тести, щоб переконатися, що помилок чи змін у поведінці не вводиться. Умови гонок (на зразок коментарів, на які натякають) є особливо важкими - це одне місце, де одиничні тести не врятують вас.

  2. Не змінювати код ризиковано . Код має велику ймовірність містити незрозумілі помилки та перегони. Якщо в коді виявлена ​​критична помилка або зміна вимог бізнесу з високим пріоритетом змушує вас змінити цей код в найкоротші терміни, у вас виникнуть великі проблеми. Тепер у вас всі проблеми окреслені в 1, але під тиском часу! Крім того, такі "темні області" в коді мають тенденцію до поширення та інфікування інших частин коду, до яких він торкається.

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

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

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


-1

Питання, яке я б задав - це чому хтось написав, НЕ редагуйте в першу чергу.

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

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

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

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

Повинно бути принаймні коментар щодо причин не редагування. Скажімо, "Не чіпай" або "Не входь". Чому б не торкнутися огорожі? Чому б не увійти? Чи не було б краще сказати: "Електричний паркан, не чіпай!" або "Наземні міни! Не вводьте!". Тоді очевидно, чому, і все ж ти все ще можеш увійти, але принаймні знаєш наслідки до того, як справи.

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

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


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