Що робити, коли код, поданий на перевірку коду, виявляється занадто складним?


115

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

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


4
З'являється чи є? Швидке вимірювання вихідних файлів підтвердить або спростує ваші підозри. Після вимірювання просто піднесіть вимірювальні числа при огляді коду та запропонуйте рефакторинг, щоб знизити номери складності.
Джон Рейнор



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

7
@PieterGeerkens Або, можливо, це занадто складно, оскільки це вирішує складну проблему?
Кейсі

Відповіді:


251

Якщо його неможливо переглянути, він не може пройти перевірку.

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

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


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

2
хороша відповідь. це залежить від мети "перегляду коду". читабельність - це одне, структура - інше, але вони дуже тісно пов'язані. fwiw Я працюю з деяким відкритим кодом, написаним корпусом MAJOR, і це майже нечитабельно, оскільки назви var та fn настільки притаманні волоссю.

19
@DavidGrinberg З усіх практичних цілей "ти за півроку" - це зовсім інша людина.
chrylis -на страйк-

2
Покладіть код на деякий час (досить довго, щоб він не запам’ятав усе). Попросіть оригінальний кодер переглянути його. Подивіться, чи ВІН це розуміє.
Нельсон

4
Я не погоджуюся з тим, що огляд коду "не" для пошуку помилок. У ньому часто виявляються помилки, і це дуже потужний і корисний аспект огляду коду. Що ще краще, це допомагає знайти способи повністю уникнути помилок у майбутньому коді. Справа, мабуть, завищена, і має бути в тому, що помилок знайти не виключно !
Коді Грей

45

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

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

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

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


30

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

Це далеко не сенс перегляду коду. Спосіб продумати огляд коду - це уявити, що в коді є помилка, і ви повинні її виправити. З цим мисленням перегляньте код (особливо коментарі) і запитайте себе: "Чи легко зрозуміти велику картину того, що відбувається, щоб я міг звузити проблему?" Якщо так, то пропуск. Інакше це невдача. Щонайменше потрібно більше документації, або, можливо, потрібен рефакторинг, щоб зробити код зрозумілим.

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


4
Чудовий коментар! "Більшість кодів стільки настільки, що його можна було легко відновити 10 разів поспіль, отримуючи з кожним разом більш читабельні" Хлопчик, чи я був винен у цьому? :)
Дін Редкліфф

1
"Більшість кодів стільки, що їх можна легко відновити 10 разів поспіль, щоразу стає читабельнішими." Дійсно, саме так і є в реальному світі.
Пітер Мортенсен

@PeterMortensen Дійсно, що у реальному світі ви багато чого знайдете. Але нікому не цікаво так писати код. Я думаю, що є дві причини, чому саме так. Освіта, яку отримують розробники, вкладає дуже мало зусиль у навчанні писати читабельний код. А в деяких підприємствах це сприймається як марна трата часу: "Якщо розробник вже написав робочий код, то чому ми повинні дбати, чи читається він чи ні? Просто доставляйте річ".
kasperd

15

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

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

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

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


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

6

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

Це новий код ? Залежно від часових обмежень, вам слід рекомендувати якомога більше рефактор. Чи добре витрачати більше часу на перегляд коду, якщо це необхідно. Ви не повинні витрачати час на 15 хвилин, знайдіть ідею і рухайтеся далі. Якщо автор витратив тиждень на те, щоб щось написати, непогано витратити 4-8 годин на його перегляд. Ваша мета тут допомогти їм рефактор. Ви не просто повертаєте код із написом "refactor. Now". Подивіться, які методи можна розбити, спробуйте придумати ідеї для впровадження нових класів тощо.


2
Ви не просто повертаєте код із написом "refactor. Now" - чому? Я отримував такі коментарі з огляду хоча б раз і востаннє, коли я пам'ятаю, це виявилося корисним та правильним. Мені довелося переписати великий шматок коду з нуля, і це було правильно зробити, тому що, озираючись назад, я сам бачив, що старий код - це незмінний безлад. Рецензент був достатньо кваліфікований, щоб помітити, що (а я, мабуть, не був)
gnat

4
@gnat: Для одного, тому що це грубо. Ви краще виглядаєте, коли пояснюєте, що з кодом не так, і докладаєте зусиль, щоб допомогти іншій людині вдосконалити його. У великій компанії, яка робить це в іншому випадку, ви можете швидко вийти з дверей. Особливо, якщо ви переглядаєте код старшої людини.
Неоліск

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

1
@gnat: Підхід "Refactor. now" може працювати вниз, тобто коли старший розробник, який має досвід 10+ років, говорить про рефактор молодшому розробнику, якого найняли 1 місяць тому без досвіду чи подібної ситуації. Вгору - у вас можуть виникнути проблеми. Оскільки ви, можливо, не знаєте, який досвід має інший розробник, можна сміливо вважати повагу поведінкою за замовчуванням. Це не зашкодить вам точно.
Неоліск

1
@Neolisk: Досвідчений розробник, якому довелося писати код під тиском часу і знає, що він недостатньо хороший, може бути надто задоволений, якщо ви відкинете код, надавши йому час і привід для його вдосконалення. PHB, який вирішив, що це досить добре, робить розробника нещасним; рецензент, який вирішив, що це недостатньо добре, робить його щасливим.
gnasher729

2

Часто "складні" патчі / списки змін - це ті, хто робить багато різних речей одночасно. З'явився новий код, видалений код, код, який переробили, переміщений код, розширені тести; важко бачити велику картину.

Поширена підказка полягає в тому, що патч величезний, але його опис крихітний: "Реалізуйте $ FOO".

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

Наприклад, перші патчі можуть містити суто механічні рефактори, які не вносять функціональних змін, і тоді остаточний патч може зосередитися на реальній реалізації та тестуванні $ FOO з меншою кількістю відволікань та червоних оселедців.

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

Що стосується цього тактовно, я зазвичай називаю це своєю проблемою, а потім прошу допомоги автора: "У мене виникають труднощі слідкувати за тим, що все відбувається тут. Чи можете ви розбити цей патч на менші кроки, щоб допомогти мені зрозуміти, як це все підходить" разом? " Іноді необхідно зробити конкретні пропозиції для менших кроків.

Настільки великий патч, як "Implement $ FOO", перетворюється на серію патчів на зразок:

  1. Представляємо нову версію Frobnicate, яка займає пару ітераторів, оскільки мені потрібно буде називати її послідовностями, відмінними від векторних, щоб реалізувати $ FOO.
  2. Переключіть усі існуючі абоненти Frobnicate, щоб використовувати нову версію.
  3. Видаліть старий Frobnicate.
  4. Frobnicate робив занадто багато. Сформулюйте фактор повторного кроку на власний метод і додайте для цього тести.
  5. Представляємо Zerzify з тестами. Ще не використовується, але мені знадобиться за $ FOO.
  6. Впровадьте $ FOO з точки зору Zerzify та нового Frobnicate.

Зауважте, що кроки 1-5 не вносять жодних функціональних змін у виріб. Вони банальні для огляду, включаючи те, що у вас є всі правильні тести. Навіть якщо крок 6 все ще "складний", принаймні він зосереджений на $ FOO. І журнал, природно, дає вам набагато краще уявлення про те, як було реалізовано $ FOO (і чому Frobnicate було змінено).


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

1

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

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

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

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

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


0

Що таке тести? Вони повинні бути чіткими, простими та легкими для читання з ідеалом лише одним твердженням. Тести повинні чітко зафіксувати передбачувану поведінку та використовувати випадки коду.

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

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