Когда проводить рефакторинг

32

Я прочитал большую часть книги Рефакторинга Фаулера и провел рефакторинг многих приложений в моем прошлом, большом и малом.

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

Я чувствую, что должны быть более строгие подходы к этому, но я не уверен, что они есть.

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

Hortitude
источник
2
По сути, вы спрашиваете то же самое, что и это: programmers.stackexchange.com/questions/6268/… . За исключением того, что ваш порог для принятия действий ниже, поскольку стоимость и риск ниже, верно?
S.Lott

Ответы:

22

Рефакторинг, когда стоимость рефакторинга меньше стоимости не рефакторинга.

Измерьте «стоимость», как вы можете. Например, настолько ли плохо реализован код, что тривиальные ошибки стоят часов или дней, чтобы их исправить? Позволит ли рефакторинг привлечь больше клиентов, или увеличить емкость, или улучшить производительность, и тем самым сделать ваших существующих клиентов счастливее?

Брайан Оукли
источник
коротко и идеально
ZJR
8
Другими словами: «стоит рефакторинг, когда стоит рефакторинг». Duh. Ну, это не совсем ответ, не так ли :) Measure "cost" however you can.- Хорошо, как? Разве это не суть вопроса? Какую временную перспективу следует применять при измерении этой стоимости?
Конрад Моравский
2
@Morawski: нет, это неправильный пересказ. Я сказал, что стоит провести рефакторинг, если стоимость, полученная от рефакторинга, превышает стоимость рефакторинга. Это не то же самое, что сказать «стоит рефакторинга, когда стоит рефакторинга». Рассчитать стоимость рефакторинга. Рассчитать стоимость не рефакторинга. Какой больше?
Брайан Оукли
@BryanOakley: проблема в том, что вы не можете «рассчитать» эти расходы. Вы можете в лучшем случае оценить их, что действительно трудно сделать, когда речь идет о стоимости не рефакторинга . Какой мультипликатор стоимости обслуживания вы применяете к нерефакторированной версии по сравнению с рефакторированной версией? Как вы узнаете, нужно ли вообще поддерживать или изменять данный код? Как вы оцениваете количество сгенерированных ошибок? В конце концов, я думаю, что все мы неосознанно делаем такие оценки в рамках нашего процесса принятия решений, когда мы думаем о рефакторинге, но от этого нельзя ожидать никакой точности.
guillaume31
1
@ ian31: правда, вы не можете рассчитать значения, и лучшее, что вы можете сделать, это оценить. Тем не менее, это единственный действительно верный способ решить, следует ли проводить рефакторинг или нет, при условии, что у вас ограничено время и ресурсы. Вам нужно решить, стоит ли этот рефактор. Как вы определяете «ценность» - очень неточная наука. Суть в том, что вы не должны рефакторировать на интуицию - должна быть веская причина для проведения рефакторинга, отличного от «Я хочу, чтобы код был красивее».
Брайан Оукли
12

  1. Является ли цикломатическая сложность функции ниже 5?
  2. Вы полностью поняли, что такое цикломатическая сложность, не переходя по этой ссылке?
  3. У вас есть автоматизированный тест или документированный тестовый пример для каждого пути через функцию?
  4. Все ли существующие контрольные примеры пройдены?
  5. Можете ли вы объяснить мне функцию и все ее крайние случаи менее чем за 1 минуту?
  6. Если нет, то как насчет 5 минут?
  7. 10 минут?
  8. Есть ли менее 100 строк кода в функции (включая комментарии)?
  9. Можете ли вы найти двух других разработчиков, которые согласны с тем, что этот код не содержит ошибок только при визуальном осмотре?
  10. Эта функция используется только в одном месте?
  11. Соответствует ли функция целям производительности (время / память / процессор)?

счет

Сложите ответы «нет» выше:

  • 0-1 - Почему вы вообще думаете об этом рефакторинге? Вы, вероятно, просто хотите переименовать переменные, потому что вам не нравится соглашение об именах предыдущего разработчика
  • 2-5 - Это может потребовать небольшой доработки, но я бы не стал задерживать производственный выпуск для чего-то в этом диапазоне
  • 6-8 - Ладно, нам, наверное, нужно это исправить ... Скорее всего, мы продолжим пересматривать это и / или мы на самом деле не знаем, что он делает. Все еще на заборе, но это очень подозрительно
  • 9+ - это главный кандидат на рефакторинг. (Обратите внимание, написание контрольных примеров является формой рефакторинга)

http://mikemainguy.blogspot.com/2013/05/when-to-refactor-code.html

Мейнгай
источник
4
# 2 звучит очень снобистски и фактически бесполезно для оценки кода . № 3 и № 4 не каждая компания использует модульные тесты. # 8 Избегайте комментариев везде, где это возможно, и 100 строк слишком высоки. У меня есть 1 большой широкоэкранный монитор в портретном режиме, и я едва смогу увидеть всю функцию сразу. Если это более 15 строк реального кода, то уже должна быть веская причина, почему вы так и продолжаете. Хороший практический подход - иметь контрольный список, но слишком много пунктов здесь просто составлены или используют случайные значения без каких-либо объяснений.
Р. Шмитц
8

Когда ваша интуиция говорит вам, что вам, вероятно, следует провести некоторый рефакторинг, скорее всего, это ваши инстинкты, говорящие вам немного поздно, что вы слишком долго откладывали что-то важное.

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

Фактически существует два уровня рефакторинга. Первый - это очевидные проблемы, которые появляются при первом коде. Это небольшие оптимизации, которые стоят очень мало, чтобы сделать заранее. Такие вещи, как сохранение ваших методов и классов маленькими, а также соблюдение DRY и SRP. Затем у вас есть дополнительный этап работы с серьезными недостатками в вашем дизайне, которые могут не сразу проявиться, пока ваш код не пройдет пару миль. Это второй уровень, о котором вы говорите, и все же, чтобы гарантировать, что последующее рефакторинг не будет слишком дорогостоящим, вы должны уже написать свой код таким образом, чтобы усилия, которые вы планируете позже, стали проще и дешевле, что означает ранний рефакторинг.

Как отметил Джефф в своем ответе, «время - деньги» , особенно в компаниях, где рабочая нагрузка высока, а риски еще выше. Время, потраченное на то, чтобы убедиться, что код находится в наилучшем возможном состоянии, сэкономит время позже, когда выявление того, что должно было быть легким рефакторингом, оказывается основной операцией.

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

В любом случае, рефакторинг не должен быть задачей, которую вы откладываете до какого-то таинственного будущего, когда программное обеспечение уже завершено и стабильно, поскольку это увеличивает ваши риски позже, когда ставки намного выше, а продукт намного сложнее изменить. Рефакторинг должен быть частью вашей повседневной деятельности, и в этом суть философии Red-Green-Refactor, которую вы упомянули.

S.Robins
источник
2

Я думаю, что на ваш вопрос могут ответить по-разному каждый разработчик и даже руководство, отвечающее за программирование.

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

В более крупной компании по разработке программного обеспечения, где время - деньги, может быть стоит начать проектирование с использованием лучших практик, которые вы узнали из этого момента, не беспокойтесь о рефакторинге до версии 2 этого конкретного программного обеспечения?

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

Джефф
источник
2

"Когда рефакторинг?"

Краткий ответ: каждый раз, когда вы сталкиваетесь с кодом, который плохо пахнет или может быть улучшен ( правило бойскаута )

Практически это происходит:

  • Если вы практикуете TDD, систематически на этапе Refactor цикла TDD, то есть, когда ваш тест зеленый и перед тем, как вы начнете писать новый тест.
  • В результате проверки кода
  • При принятии старого кода
  • При использовании кода, который кажется неуклюжим
  • и т.п.
guillaume31
источник
Я чувствую, что это просто говорит: «Вы должны провести рефакторинг», не отвечая на более сложную часть: «Я чувствую, что к этому должны быть более строгие подходы, но я не уверен, что они есть».
Hortitude
Я не знаю, что сказать, кроме как чувствовать, что больно поддерживать, нюхать запахи кода и использовать свой опыт. Я сомневаюсь, что когда-либо найдется окончательный, устоявшийся метод, который скажет вам, когда и что нужно проводить рефакторинг, если это то, что вы ищете.
guillaume31
1

Когда я впервые узнал о рефакторинге, мой наставник сказал мне: «Сделай это дважды, держи нос. Сделай это три раза. Рефакторинг». (Спасибо, Джош!) Если быть точным, то, что он говорил, было то, что когда вы собираетесь написать один и тот же блок кода в третий раз (или даже похожий шаблон кода), это время для рефакторинга. Я следил за этим в течение последних 10 лет и нашел, что это достаточно здравое правило.

Использование Eclipse или аналогичной среды IDE, которая имеет мощную поддержку рефакторинга, сокращает усилия по проведению рефакторинга. Поддержка IDE повышает вероятность того, что вы проведете рефакторинг, как только вы нажмете «третий раз» (или увидите необходимость), вместо того, чтобы рассматривать это как дополнительное усилие.

Кроме того - TDD также очень помогает, так как вы можете продолжать выполнять свои тесты в качестве рефакторинга и знать, что ничего не сломали.

Сэм Голдберг
источник
1

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

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

0lukasz0
источник
1

За мои 20 лет программирования, вот единственное эмпирическое правило, которое я на самом деле видел на работе, к которому люди могут привязаться, и у менеджеров есть время. (Рефакторинг подобен диете: конечно, «калорийность / калорийность» - это формула для похудения, но это не означает, что люди будут соблюдать диету). И так:

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

Как только вы станете более уверенным в себе, вы можете изменить этот режим.

Dogweather
источник
1

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

Что касается технических причин, то их несколько.

  • Если у вас есть ошибка в коде, это означает, что это место неправильно понято, и ОЧЕНЬ вероятно, что здесь может быть скрыто больше ошибок, и, безусловно, возникнут большие проблемы с любой попыткой разработки связанных частей кода. Таким образом, это место должно быть проверено на предмет возможного рефакторинга.
  • Другая причина - когда вы добавляете или изменяете функцию, и старый код очень неудобен для изменения / добавления, а последующие изменения / добавления весьма возможны. Конечно, вы должны сбалансировать стоимость.
  • Возможно, самая серьезная причина - когда вы меняете код, и он не тестируется.
Гангнус
источник
Будучи мастером схватки, у нас был разработчик, который постоянно утверждал, что каждая история, в которой участвовала команда, была больше, чем она думала, и обнаружил, что хочет реорганизовать каждый фрагмент кода, с которым столкнулся. Таким образом, история из 3 пунктов всегда была для него 8. Ясно, что это испортило доставку ценности. Так или иначе, должно быть некоторое понимание того, когда проводить рефакторинг и как должно быть принято решение. Просто моя мысль, из этого (и нескольких других) опыта.
Кертис Рид,