Где рефакторинг и оптимизация кода должны сочетаться как с гибкой, так и с временной шкалой процесса?

10

Похоже, среди команды управления проектом существует такое понятие, что «это работает» означает, что его следует считать завершенным на 100%. Большинство программистов знают, что это не всегда так. Если я пробую альтернативные подходы, чтобы заставить работать часть функциональности, это не обязательно означает, что я нашел лучшее решение, или это не потребует некоторых переделок после рассмотрения с другими разработчиками. Я часто что-то делаю, делаю шаг назад и спрашиваю себя, что я могу сделать лучше после того, как бизнес-правила будут выполнены. Должно ли это время «я могу сделать лучше» вписаться где-то в сроки? Я считаю, что лучший подход заключается в том, что вы всегда оставляете код лучше, чем когда вы его находите (до некоторой степени), что может означать рефакторинг после запуска. Однако,


источник

Ответы:

13

Существует один всеобъемлющий принцип, который регулирует необходимость рефакторинга и оптимизации как в водопаде, так и в Agile: YAGNI (вам это не нужно). Второй принцип является следствием первого: «Преждевременная оптимизация - корень всего зла», кодовый эквивалент общей пословицы «враг совершенства - совершенство».

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

Вы умный парень, и вы получили представление о большой картине. Вы знаете, что это не единственный тип файла, для которого проекту понадобится ETL. Итак, вы рассматриваете реализацию этого алгоритма ETL, чтобы также работать с файлами другого типа, у которых есть только незначительные различия. Это нарушит YAGNI. Ваша задача - не разрабатывать алгоритм для этого другого файла; это разработать алгоритм для одного файла, который нужен к концу недели. Чтобы достичь этой цели и пройти приемочные тесты, вам нужно разработать этот алгоритм и заставить его работать правильно. Вам не понадобится дополнительный код, чтобы он работал с другим файлом. Вы можете подумать, что это сэкономит вам время, чтобы включить его сейчас, и вы можете быть правы, но вы также можете быть ужасно неправы; алгоритм для другого файла, возможно, придется использовать в той части системы, в которой ваш код не может быть использован, или требования к новому файлу могут отличаться от ваших, если вы не знаете (в Agile требования могут еще не существовать). Тем временем вы потратили впустую время и излишне увеличили сложность своего алгоритма.

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

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

Следуйте этому простому процессу при разработке, будь то в Agile или в традиционных SDLC: «На первом проходе сделайте так, чтобы он работал. На втором проходе сделайте его красивым. На третьем проходе сделайте его твердым». Это означает, что когда вы впервые создаете строку кода, заставьте этот код выполнять свою работу правильно и без ошибок, но не обращайте слишком много внимания на правила разработки в этом коде, как вы уже знаете сейчас ». Я никогда не коснусь этой области снова. В следующий раз, когда вы посещаете эту строку кода, вы просто доказали, что ошибаетесь; это больше не единственная часть системы. Рефакторинг его для удобочитаемости, краткости кода и / или принципов СУХОГО (возможно, вы скопировали некоторый код, чтобы сделать что-то пять раз; реорганизовать его в цикл и / или вызов метода). В третий раз, когда вы работаете в или около этой строки кода,

Keiths
источник
3
+1, O(my God)-complexityесли не что иное, заставило меня смеяться!
Джоэл К,
+1 для Получите это работает первым. Слишком много людей пытаются писать шаблоны и преждевременно оптимизировать их.
Джастин Шилд
Я считаю, что это одна из самых трудных проблем, которую нужно преодолеть программисту. У инженеров есть врожденное желание экспериментировать, развиваться и совершенствоваться, но в конце концов вам платят за производительность. Что хорошего в идеальном продукте, если вы тратите столько времени и / или денег, что он отменяется из-за переполнения?
ToddR
Мне нравится прагматический подход, но у меня есть проблема с «На втором проходе, сделай его красивым»: если 2-й проход - год спустя, и ты не уверен, что имена переменных и методов имеют смысл, а магические числа заменены символическими константами. у вас, вероятно, есть проблемы с пониманием кода. Как с этим бороться? «Сделать это красиво» через 1 час после «заставить его работать» намного дешевле, чем «сделать это красиво» через месяц или год. Я согласен с тем, что "сделать это красиво", когда необходимо следующее изменение кода, полезно, если "сделать это красиво" не было сделано в первую очередь.
k3b
В Agile / TDD мой опыт показывает, что второй проход обычно происходит довольно скоро после первого. В SLDC с водопадом вы более правы; функция имеет тенденцию быть написанной один раз и затем сидеть там, пока не пройдет следующий раунд требований, которые касаются этого метода. Итак, в первый раз должны произойти некоторые хорошие практики кодирования, такие как самодокументируемый код, чтобы, когда вы вернетесь год спустя, вы могли вспомнить, что делает код и почему вы его так написали.
KeithS
10

если это работает, и было проверено, то зачем это исправлять?

Это может идти вразрез с вашим личным темпераментом как инженера / программиста, но если это работает, какая ценность для бизнеса для вас, чтобы продолжать улучшать его? Будет ли это легче поддерживать со временем? Если это так, то, работая в рамках гибкой методологии, вы сможете создавать новые элементы в своем бэклоге, чтобы уточнить и реорганизовать существующий код, и они будут иметь приоритет над другими элементами в бэклоге. Это часть ценности гибкого процесса: команда вместе решает, что наиболее важно и что будет сделано дальше.

Наша команда также отслеживает то, что мы называем «техническими долгами», поэтому, если у вас что-то работает, но вы знаете, что это можно сделать лучше, вы регистрируете это как технический долг. Мы используем scrum, и иногда вы заканчиваете всю работу в спринте рано (вы должны закончить немного раньше, примерно наполовину, если вы достаточно близки с оценками), но у вас не будет достаточно времени, чтобы начать совершенно новый пользовательская история, поэтому мы тратим дополнительное время, возвращаясь и исправляя наш технический долг. Он не отслеживается формально, как наши пользовательские истории в нашем бэклоге, и мы можем в значительной степени работать над этим, когда у нас есть свободное время.

Это также более или менее решительный вызов с вашей стороны, когда вы называете задачу «выполненной»; если вас не устраивает состояние вашего кода, не помечайте задачу как выполненную.

Джоэл С
источник
2
Я стал поклонником концепции «технического долга», +1 за то, что поднял ее в этом контексте.
Патрик Хьюз
Полностью забыл про идею «технического долга»; хороший срок. Но меня учили, что следует избегать всего, что квалифицируется как «технический долг», то есть для его рефакторинга требуются значительные циклы разработки; «сделать это светло» все еще означало «делать это правильно», только не используйте «башню из слоновой кости» для кода, который может быть одноразовым.
KeithS
5

Должно ли это время «я могу сделать лучше» вписаться где-то в сроки?

Да.

Непосредственно перед тем, как вы начнете кодировать следующий выпуск.

Не рефакторинг, основанный на «интуиции».

Рефакторинг, основанный на реальных историях следующего спринта.

С. Лотт
источник
2

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

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

mpenrow
источник
1
Код не является «завершенным на 100%», пока все продукты, в которых он находится, не устареют. Как будто вы не «завершены» как личность, пока ваше сердце не перестанет биться постоянно; вы всегда будете получать новую информацию и будете обязаны делать определенные вещи, которые вы никогда не делали раньше, или делать то же самое новым, более эффективным или менее дорогим способом. Точно так же ваша кодовая база ВСЕГДА будет нуждаться в работе - новых функциях и старых исправлениях - до тех пор, пока никто больше не будет использовать программное обеспечение.
KeithS
2

«Рефакторинг после запуска» имеет скрытую стоимость в регрессионном тестировании и времени QA, которое вы игнорируете, плюс он несет альтернативную стоимость отсутствия работы с сообщенными ошибками и новыми / запрошенными функциями и изменениями. TANSTAAFL

Если это стоит сделать, стоит поставить задачу, чтобы расставить приоритеты через обычный процесс, а не как специальное исключение. В конце концов, вы являетесь частью команды и работаете над общими целями и произвольно расширяете свой график, чтобы приспособиться к исправлению рабочего кода.

Так что для реального ответа: если вы знаете, что вы хотите рефакторинг, то запланируйте это время как часть задачи. Если вы делаете scrum / agile, тогда поставьте время на очистку. Если вы водопад / спираль, то сделайте рефакторинг частью процесса для проверки кода и принятия модулей.

Патрик Хьюз
источник
0

Если я пытаюсь использовать альтернативные подходы, чтобы заставить работать часть функциональности, это не обязательно означает, что я нашел лучшее решение,

... В этом случае вы еще не сделали 100% ...

или это не потребует некоторой переделки после рассмотрения с другими разработчиками.

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

Я часто что-то делаю, делаю шаг назад и спрашиваю себя, что я могу сделать лучше после того, как бизнес-правила будут выполнены. Должно ли это время «я могу сделать лучше» вписаться где-то в сроки?

Это зависит. Если это означает рефакторинг, это должно быть частью первоначальной задачи разработки. Если это означает экспериментировать с потенциально лучшим алгоритмом, это может быть отдельной задачей.

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

Вкратце, потому что код может быть разбит на многих уровнях.

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

Более подробные ответы смотрите в этой теме .

Петер Тёрёк
источник
0

Насколько я могу видеть и читать, это нерешенный вопрос. Следовательно, ответы избегания, такие как "ЯГНИ" и ответы "сделай это правильно в первый раз". Дело в том, что в Agile нет места для рефакторинга, но я бы сказал, что так должно быть.

Лучший ответ на данный момент упоминает технический долг. К сожалению, это печальная реальность программного обеспечения на многих предприятиях, где стремление получить что-то вне дома, будь то в гибкой или негибкой методологии, является обычным делом, но в Agile быстрые и грязные решения рационализируются как нечто хорошее: «соответствует минимальным требованиям бизнеса» и «YAGNI» (с точки зрения поддержания чистоты кода).

Было бы здорово, если бы все делали TDD, и было бы здорово, если бы все разработчики рефакторировали второй или третий раз, как это было предложено одним ответом. Но этого просто не бывает в реальном мире. Оказывается, что разработчики с разным уровнем квалификации почти всегда находят отрезки в поисках быстрых решений. В результате код распадается в горы неуправляемого кода, а новым разработчикам нужны дни, чтобы его расшифровать, что снижает производительность и задерживает сроки. Под «неуправляемым» я подразумеваю решения для копирования и вставки, 5000 линейных классов и т. Д. И весь этот код и эти исправления после исправлений являются основными для бизнеса! - Я бы сказал, что в этих случаях аддитивных растворов нет такой вещи, как YAGNI! Вам понадобится чистый код - ВСЕГДА. Если код не чистый, вы определенно не нуждаетесь в нем - посмотрите самоисполняющееся пророчество? Разработчики пошли бы на все, чтобы вообще не использовать этот код, потому что на него слишком больно смотреть. И порочный круг продолжается и продолжается до тех пор, пока весь большой шарик грязи не будет заброшен и переписан.

Поэтому я говорю - несмотря на то, что рефакторинг кода не является надлежащей, внятной, достойной своего рода концепцией Agile-типа, мы должны уделить время рефакторингу. Некоторые магазины сейчас требуют, чтобы команды тратили 20% своих спринтов на технические долги. Надеюсь, проворные сторонники изменят свое мнение о YAGNI и создадут место для рефакторинга как отдельного времени, отведенного для этого. И если они уже сделали, и я не слышал об этом, пожалуйста, укажите, где это описано, потому что мне очень интересно знать.

blindcodifier9734
источник
«Дело в том, что в Agile нет места для рефакторинга» - я не думаю, что это верное утверждение. В Agile есть место для любых разработок, включая рефакторинг, если для этого есть экономическое обоснование. Если для этого нет бизнес-обоснования, зачем вы это делаете?
Брайан Оукли
Я думаю, у вас есть смысл, если немного упрощенно. Теоретически, разработчик мог бы сфабриковать экономическое обоснование для исправления некачественного кода, даже если он не приводит к каким-либо функциональным изменениям, но это не соответствовало бы духу гибкости - использование бизнеса в качестве прокси для оправдания работы. Тогда я бы сказал, что деятельность по рефакторингу выходит за рамки гибкой - что-то вроде деятельности CYA, если хотите, - исправляет не поддерживаемый код, чтобы он не стоил бизнесу в долгосрочной перспективе, и виноваты разработчики. Назовите это «рефакторинг спринт» или что-то, но должно быть формальное место для этого.
blindcodifier9734