Как вы перестаете рефакторинг рабочего, но ужасного кода?

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

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

Ответ 1

То, что сработало для меня, было уволено с работы за него.:\

Тем не менее, моя основная проблема была двоякой:

  • Я был рефакторингом, который никто не просил меня работать.

  • Мне было слишком сложно проводить тесты на месте, поэтому я сделал это без них. Что, естественно, сломало некоторые вещи.

То, что я узнал, было:

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

  • Если вам нужен код рефакторинга, на котором вы должны работать, у вас есть тесты, но им не нужно автоматизировать.

После прочтения слишком большого количества материалов TDD я, как правило, думал о автоматизированных тестах как о единственном типе тестов. На самом деле даже куча операторов Debug.Print может быть достойным тестом, чтобы выяснить, поддерживает ли функциональность.

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

Ответ 2

Ответ: нет. Просто потому, что работает код, это не значит, что он всегда будет работать. Плохой код - это плохой код.

Мы реорганизуем, чтобы сделать код более читаемым, более простым в обслуживании и обеспечить надежность.

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

Я всегда стараюсь оставить код лучше, чем нашел.

Ответ 3

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

Ответ 4

Я не буду говорить, что я страдаю от этого несчастья, но... Я слышу тебя, брат!

Мне кажется, нам нужно оставить код в лучшем состоянии, чем когда мы его оставили. Итак, ваше преследование благородно. Позвольте называть его "рефакторит".

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

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

Спасибо за интересный вопрос. Это заставляет меня задаться вопросом, нужна ли нам группа "Refactorors Anonymous", где мы можем сидеть в кругу и делиться своими проблемами и историями войны.

Ответ 5

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

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

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

Ответ 6

Мартин Фаулер берет на себя эту проблему:

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

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

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

Ответ 7

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

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

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

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

Если у вас нет ограничений на коммерческую разработку программного обеспечения, ваш пробег может отличаться.;)

Кстати, хороший вопрос - я тоже задумываюсь о том, где рисовать линию довольно часто.

Ответ 8

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

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

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

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

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

Изменить: У Джоэл Спольски есть лучший ответ, я считаю.

Ответ 9

Совершенно правильный вопрос.

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

Это привело меня в привычку постоянно спрашивать себя: Является ли код, который я пишу сейчас, чтобы помочь мне выполнить эту задачу за разумное время? Я "трачу" время компании, выполняя этот рефакторинг, в то время как есть заметные позиции, которые намного выше в списке приоритетов?

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

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

Как только вы найдете время, вернитесь и рефакторинг.

Ответ 10

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

Два предложения:

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

Ответ 11

Следующее правило бойскаута применяет очень хороший (плохой) код и дизайн:
Оставьте уборщик лагеря, чем вы его нашли!

Ответ 12

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

Я БОЛЬШОЙ поклонник doxygen, который позволяет мне придерживаться простого:

/**
 * Function to rule the world
 * @todo make this actually work
 */

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

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

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

После того, как вы привыкли ко всему коду и немного подумали о том, как сделать вещи более связными... затем погрузиться. В противном случае, вы в конечном итоге будете перефакторировать свой предыдущий ре-факторинг (какой порочный цикл, который занимал годы совершенствовать!).

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

Ответ 13

Во-первых, вы должны понять и принять, что единственная причина, по которой имеет значение плохой код, - это его чтение и/или изменение. Его нужно читать и/или изменять, если вы ищете ошибку или добавляете функциональность. Так что только прикоснитесь к коду, если вы исправляете или улучшаете ошибки. Итак, если вы сталкиваетесь с некоторыми массово вложенными операторами if-then-else или с плохой именованной переменной или методом, оставьте ее в покое, если вам не нужно действительно понять или изменить этот код, чтобы завершить задачу, над которой вы на самом деле работаете. Если вам нужно изменить код, то достаточно реорганизовать его, чтобы сделать код понятным и изменить его легче, но не более.

Ответ 14

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

Ответ 15

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

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

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

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

Ответ 16

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

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

Отношение, которое после рефакторинга рабочего кода "Я оставил код лучше", часто является программистом hubris. Во многих случаях вы действительно не знаете, что вы оставили код лучше, вы просто полагаете, что сделали. Если вы даже не исправили ошибку или не добавили функциональность, зачем рисковать быть неправым?

Ответ 17

Прекратите заботу.

Я имею в виду, cmon, мы все инженеры здесь, и инженеры просто любят выпускать САМОСТОЯТЕЛЬНЫЙ СОВЕРШЕННЫЙ СОВЕРШЕННЫЙ КОД. И мы будем продолжать пытаться. И мы не будем довольны нашей работой, если не знаем, что все, что мы коснулись, это TMAPCE. Кроме того, мы просто знаем, что этот способ намного лучше...

Итак, единственный реальный способ не пытаться реорганизовать еще немного, за исключением того, что вам не нужна ваша работа. (Как я заметил, это случилось со мной однажды. Было очень грустно... пока я перешел на другую работу.)

Ответ 18

Я расставляю приоритеты.

Когда у меня есть несколько доступных циклов (га),

Обычно я пытаюсь перефразировать код, который:

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

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

Причины не касаться ничего, что мы чувствуем, как касаться?

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

Ответ 19

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

По-прежнему стоит потратить и выиграть, но в принципе я согласен с Longhorn, что вы не должны останавливаться.

Ответ 20

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

Ответ 21

Прежде чем приступить к рефакторингу, для этого вам необходимо иметь исчерпывающие модульные тесты, и никто не любит писать модульные тесты:)

Ответ 22

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

Ответ 23

Я создаю проблему в нашем трекере проблем (или вы можете использовать примечание post-it) об исправлении этого кода, а затем забудьте о проблеме.

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

Ответ 24

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

До тех пор я просто буду замечать идеи для изменений в комментариях.

Ответ 26

Это очень просто.

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

EDIT: Даже если ваша компания не имеет такой политики, просто помните, что вам нужно проверить, что вы меняете. Оцените время, необходимое для проверки ваших изменений.

Отвечая на вопрос "Что такое добавленное значение?" также помогает.

Ответ 27

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

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

  • Я буду работать с этим кодом ежедневно в течение длительного периода И я ТОЛЬКО человек, который будет.
  • Является ли код настолько плохим, что его невозможно правильно понять. Обычно я нахожу, что я просто страдаю от случая не выдуманного здесь синдрома (вещь, где кто-то еще отлично подходит, не так, как я бы сделал это, поэтому я хочу сделать это снова без реальной выгоды, кроме гордости).
  • Является ли архитектура не способной поддерживать новую работу (функция, исправление ошибок и т.д.).
  • Является ли этот код таким кровосмесительным, что изменение нескольких мелких вещей имеет массивный пульсационный эффект последующих ошибок.

Если вы ответите "да" на любой из них, возможно, настало время для рефакторинга.

Ответ 28

Я страдал от этого в прошлом, и я микроуправляю свою "плохую" хорошую привычку.

В основном, я делаю следующее:

  • У меня есть два отдельных экземпляра нашего исходного дерева в любой момент времени.
  • Если у меня есть массивный рефактор, который не является главным приоритетом, я отрываю его во второй ветке.
  • Затем я продолжу работать в своем первом филиале и просто поддерживаю вторую ветку, делая небольшие тесты, поскольку я думаю об этом, чтобы убедиться, что я ничего не сломал.
  • Затем я проверю его, как только я буду уверен, и я смогу время его замедлить в нашем производственном цикле (т.е. не проверять прямо до этапа!).

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

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

В любом случае. Возможно, это больше свалка мозга, чем вы заботитесь, но, надеюсь, это помогает.

Ответ 29

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

Ответ 30

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