Осуществить рефакторинг/переписать код или продолжить?

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

Причины я чувствую себя беспокоящимся о коде:

  1. Иерархия классов сложна и не очевидна
  2. Некоторые классы не имеют четко определенной цели (они делают много несвязанных вещей),
  3. Некоторые классы используют внутренности других (они объявляются как друг классы) обойти слои абстракции для производительности, но я чувствую, что они повреждают инкапсуляцию путем выполнения этого
  4. Некоторые классы пропускают детали реализации (например, я изменился, карта к хешу отображаются ранее и имел необходимость для изменения кода в других исходных файлах, чтобы внести изменение работать),
  5. Мое управление памятью / объединение системы является довольно неуклюжим и меньше прозрачным

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

Так, что думает stackoverflow? Чистый код или работа над функциями?

8
задан 14 May 2010 в 23:58
поделиться

15 ответов

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

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

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

5
ответ дан 5 December 2019 в 14:01
поделиться

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

0
ответ дан 5 December 2019 в 14:01
поделиться

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

Возможно, переделайте api/интерфейс на основе кода потребителя и проведите рефакторинг сверху вниз.

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

0
ответ дан 5 December 2019 в 14:01
поделиться

На самом деле это не так сложно. Просто следуйте этому правилу:

Рефакторить код часто. Рефакторить каждый раз, когда это возможно.

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

0
ответ дан 5 December 2019 в 14:01
поделиться

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

Цикл TDD - КРАСНЫЙ-ЗЕЛЕНЫЙ-РЕФАКТОР , и он говорит, что вы не «закончили», пока дизайн не станет хорошим, то есть до тех пор, пока он не перестанет нуждаться в рефакторинге.

0
ответ дан 5 December 2019 в 14:01
поделиться

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

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

Некоторые другие важные вещи, которые следует учитывать:

  • Удобство обслуживания - Насколько легко будет исправить неизбежные ошибки, которые появятся?
  • Тестируемость - Приведение кода к более тестируемой форме - отличный способ его рефакторинга. Добавление модульных тестов означает, что вы можете вносить изменения и точно знать, что сломалось.
  • Расширяемость - Как вы думаете, вам когда-нибудь понадобится добавлять новые функции?

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

0
ответ дан 5 December 2019 в 14:01
поделиться

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

Кроме того, одна из основных целей написания программного обеспечения (на мой взгляд) - это управление сложностью. Если у вас это работает, вы сделали половину работы. Другая ОЧЕНЬ важная половина работы - сделать вещи достаточно простыми для понимания и изменения. Без этого вы создаете программное обеспечение, которое плохо реагирует на изменения. И программное обеспечение нужно менять. Часто.

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

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

1
ответ дан 5 December 2019 в 14:01
поделиться

"Я только что закончил..."

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

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

В будущем я бы серьезно задумался о том, чтобы замедлиться и думать наперед, когда вы пишете код. Рефакторинг (или факторинг!) по ходу работы намного проще, и у вас не будет давления "но это работает", чтобы просто оставить все как есть.

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

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

1
ответ дан 5 December 2019 в 14:01
поделиться

Выполните рефакторинг.

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

2
ответ дан 5 December 2019 в 14:01
поделиться

Работайте над теми аспектами, которые позже приведут к ошибкам. Не озолотитесь.

1
ответ дан 5 December 2019 в 14:01
поделиться

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

ИМХО, конечно.

0
ответ дан 5 December 2019 в 14:01
поделиться

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

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

0
ответ дан 5 December 2019 в 14:01
поделиться

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

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

1
ответ дан 5 December 2019 в 14:01
поделиться

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

1
ответ дан 5 December 2019 в 14:01
поделиться

Итак, что думает stackoverflow? Чистый код или работа над функциями?

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

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

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

Во всех остальных случаях вам лучше провести рефакторинг.

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

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

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

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

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

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

0
ответ дан 5 December 2019 в 14:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: