Де повинні рефакторинг коду та оптимізація коду підходити як до гнучкої, так і для водоспадної процедури?


10

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

Відповіді:


13

Є один загальний принцип, який регулює необхідність рефакторації та оптимізації, як у водоспаді, так і у Agile: YAGNI (You Ant't Gonna Need It). Другим принципом є наслідок першого: "Передчасна оптимізація - корінь усього зла", кодуючий еквівалент загального прислів'я "ворог досконалості - досконалість".

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

Ти розумний хлопець, і тобі дали уяву про велику картину. Ви знаєте, що це не єдиний тип файлу, для якого проекту знадобиться ETL. Отже, ви розглядаєте можливість реалізації цього алгоритму ETL для роботи над іншим типом файлів, які мають лише незначні відмінності. Це може порушити YAGNI. Ваше завдання - не розробити алгоритм для цього іншого файлу; це розробити алгоритм для одного файлу, який потрібен до кінця тижня. Щоб досягти цієї мети і пройти тести прийняття, вам потрібно розробити цей алгоритм і змусити його правильно працювати. Вам "не знадобиться" додатковий код, щоб він працював з іншим файлом. Ви можете подумати, що це заощадить ваш час, щоб включити його зараз, і ви можете мати рацію, але ви також можете страшенно помилитися; алгоритм для іншого файлу, можливо, потрібно буде використовувати в області системи, коду не можна використовувати, або вимоги до нового файлу можуть бути іншими, ніж для вашого способу, якого ви не знаєте (у Agile, ці вимоги можуть ще не існувати). Тим часом ви витратили час і зайво збільшили складність свого алгоритму.

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

Під час розробки ви знаєте, що у вас є вимога, щоб система могла обробляти 10 КБ необроблених даних за секунду. Ви робите тест навантаження та знаходите, що ваш початковий алгоритм чернетки обробляє 8 КБ / с. Ну, це не передасть ААТ. Ви подивіться і побачите, що у вашому алгоритмі є якась структура циклу комплексності O (мій Боже); ви впорядкуєте його і отримаєте 12 КБ / с. "Дуже добре", ви думаєте, "але якщо у мене була бідна петля в коді, що ще я можу збрити?". гудіти Ви просто порушили «передчасної оптимізації» правила. Ваш код працює і проходить усі вимоги. Ви готові до тих пір, поки вимоги не будуть оновлені, щоб вимагати 15 КБ / с. Якщо і коли це трапиться, ТОГО ви потягнете код назад і шукаєте, щоб покращити.

Дотримуйтесь цього простого процесу, розробляючи, будь то в Agile або в традиційних SDLC: "На першому проході змусьте його працювати. На другому проході зробіть його гарним. На третьому проході зробіть його твердим". Це означає, що коли ви вперше створюєте рядок коду, змушуйте цей код виконувати свою роботу правильно і без помилок, але не звертайте занадто багато уваги на правила дизайну в цьому коді, як на все, що ви зараз знаєте " Ніколи більше не торкайтесь цієї області. Наступного разу, коли ви відвідуєте цей рядок коду, ви просто довели себе неправильно; це вже не одноразова частина системи. Refactor - це для читабельності, стиснення коду та / або принципів DRY (можливо, ви можете скопіювати якийсь код, щоб зробити щось п’ять разів; рефактор, який перебуває у циклі та / або виклик методу). Третій раз ви працюєте в цьому рядку коду чи навколо нього,


3
+1, O(my God)-complexityякщо нічого іншого не змусило мене сміятися!
Джоель С

+1 для початку. Занадто багато людей намагаються писати шаблони і передчасно оптимізувати їх.
Джастін Шилд

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

Мені подобається прагматичний підхід, але у мене є проблема з "На другому проході, зробіть це гарненько": якщо другий прохід буде через рік, і ви не переконайтесь, що назви змінних та методів значущі, а магічні числа були замінені символічними константами у вас, ймовірно, є проблеми з розумінням коду. Як з цим боротися? "Зробити це гарним" через 1 годину після "змусити його працювати" набагато дешевше, ніж "зробити його гарним" через місяць або через рік. Я погоджуюся, що "зробити це гарним", коли необхідна наступна зміна коду, є корисною, якщо "зробити це гарним" не було зроблено в першу чергу.
k3b

В Agile / TDD мій досвід, коли другий прохід, як правило, відбувається досить скоро після першого. У SLDCs Waterfall-ish ви маєте більше права; функція прагне писати один раз, а потім сидить там, поки наступний раунд вимог не відбудеться, що стосується цього методу. Отже, деякі добрі практики кодування повинні відбуватися вперше, наприклад, код самодокументування, так що, повернувшись через рік, ви зможете згадати, що робить код і чому ви його написали саме так.
KeithS

10

якщо він працює і був перевірений, то навіщо це виправляти?

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

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

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


2
Я став прихильником концепції "технічної заборгованості", +1 за її виведення в цьому контексті.
Патрік Х'юз

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

5

Чи повинен цей час "я можу зробити кращий" насправді вписуватися десь на часовій шкалі?

Так.

Незадовго до початку кодування наступного випуску.

Не використовуйте рефактор на основі "інтуїції".

Рефактор заснований на фактичних історіях наступного спринту.


2

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

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


1
Код не є "100% повним", поки всі продукти, в яких він мешкає, не мертві. Так само, як ви не «повноцінні» як людина, поки ваше серце перестане битися постійно; Ви завжди будете поглинати нову інформацію і від вас вимагати робити конкретні речі, яких ви ніколи не робили, або робити те ж саме по-новому, більш ефективно або менш дорого. Аналогічно, Вашій кодовій базі ВЖЕ буде потрібна робота - нові функції та старі виправлення - поки ніхто більше не використовує програмне забезпечення.
KeithS

2

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

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

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


0

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

... У такому разі ви ще не на 100% готові ...

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

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

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

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

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

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

Одна справа, що вона працює зараз. Зовсім інша річ, чи вона є чистою, розширюваною та підтримуваною у довгостроковій перспективі.

Детальніші відповіді див. У цій темі .


0

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

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

Було б чудово, якби всі робили TDD, і було б чудово, якби всі розробники повторно відремонтували другий чи третій раз, як було запропоновано однією відповіддю. Але цього в реальному світі просто не відбувається. За розробниками різного рівня навичок майже завжди виявляється, що вони вирізали кути у пошуках швидких рішень. В результаті код занепадає в гори нездійсненного коду, який потребує нових розробників днів просто для розшифровки, що шкодить продуктивності та затримує терміни. Під "нездійсненним" я маю на увазі рішення копіювання та вставки, 5000 ліній класів тощо. І весь цей код і ці виправлення після виправлень - все основні для бізнесу! - У цих випадках адитивних рішень, я заперечую, немає такого поняття, як YAGNI! Вам знадобиться чистий код - ЗАВЖДИ. Якщо код не чистий, ви, безумовно, будете - не потребуєте - бачите самореалізаційне пророцтво? Розробники намагаються не використовувати цей код взагалі, оскільки це занадто боляче. І порочний кругообіг продовжується і продовжується до тих пір, поки весь великий грязьовий бал не повинен бути зафіксований і переписаний.

Тому я кажу: незважаючи на те, що кодовий рефакторинг не є належною, чіткою, гідною концепцією Agile типу власного оповідання - ми повинні зробити час для рефакторингу. Деякі магазини зараз вимагають, щоб команди витратили 20% спринту на технічну заборгованість. Сподіваємось, спритні прихильники передумають про YAGNI та зроблять місце для рефакторингу, як окремого відведеного часу. І якщо вони вже є, а я про це не чув, будь ласка, вкажіть, де це описано, тому що мені дуже цікаво це знати.


"Справа в тому, що в Agile немає місця для рефакторингу" - я не думаю, що це правдиве твердження. У поворотному місці є місце для будь-якого розвитку, включаючи рефакторинг, якщо є бізнес-приклад для цього. Якщо для цього немає ділової справи, чому ви це робите?
Брайан Оуклі

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