Ведение кода: сохранение плохого паттерна при расширении нового кода для обеспечения согласованности или нет?


45

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

Нужно ли мне:

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

или же

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

Точность отредактировано после первых ответов:

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

Я не хочу проводить рефакторинг, потому что у меня нет времени. И даже со временем будет трудно обосновать, что весь прекрасно работающий модуль нуждается в рефакторинге. Стоимость рефакторинга будет выше, чем его преимущества. Помните: код не является грязным или слишком сложным. Я не могу извлечь несколько методов там и ввести абстрактный класс здесь. Это скорее недостаток в дизайне (я думаю, что это результат «Keep It Stupid Simple»)

Таким образом, вопрос также может быть задан так:
Вы, как разработчик, предпочитаете ли вы поддерживать простой тупой скучный код ИЛИ иметь помощников, которые будут делать глупый скучный код у вас?

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


Очень интересный вопрос!
Филипп

1
Ведение простого скучного глупого кода - по определению легко. Я предпочел бы иметь легкую жизнь и уйти рано каждый день.
quick_now

Да, но я слишком ленив, чтобы делать скучный глупый код :) Я предпочитаю много работать 2 или 3 дня, чтобы создать что-то, что сделает эту часть для меня!
Гийом

1
Когда глупо или скучно запуталось?
Эрик Реппен

Привет, Эрик, иногда код, который можно было бы разложить на части, проще читать: это в десятки раз одно и то же, а код прост. Вы можете прочитать его подряд, не думая об этом, и вы можете отлаживать линейным способом. Здесь нет скрытой сложности.
Гийом

Ответы:


42

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

В общем, старайтесь немного улучшить код всякий раз, когда вы к нему прикасаетесь. Следуйте правилу бойскаутов ( придумано Робертом К. Мартином ), оставив код чище, чем вы его нашли. Когда вы добавляете новый код, старайтесь отделить его от существующего плохого кода. Например, не хороните его в середине длинного метода, вместо этого добавьте вызов отдельному методу и вставьте туда свой новый код. Таким образом, вы постепенно увеличиваете островки чистого (er) кода в существующей кодовой базе.

Обновить

Стоимость рефакторинга будет выше, чем его преимущества. [...] Вы, как разработчик, предпочитаете поддерживать простой тупой скучный код ИЛИ иметь помощников, которые будут делать глупый скучный код на вашем месте?

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

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

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


7
Так легко попасть в ловушку «код уже отстой, может с таким же успехом продолжать его ...» Хорошие программисты этого не делают. Хороший ответ.
sevenseacat

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

2
@ Стивен, это хорошо, если вы можете себе это позволить . В большинстве реальных проектов вы не можете просто остановить все и потратить несколько дней или недель подряд только на рефакторинг. Даже если вам повезло, что у вас есть менеджер, который его поддерживает, проект все равно нужно продолжать.
Петер Тёрёк

1
@ Стивен, это зависит - см. Мое обновление выше.
Петер Тёрёк

1
@ Петер Török: Хорошее обновление! Идеальное описание факторов реального мира, которые необходимо учитывать.
Стивен Джеурис

4

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


3

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

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


3

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

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

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


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

1

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

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

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

Обновление, касающееся ответа Петера Торока: не откладывает ли рефакторинг «потому что это требует времени», время на его рефакторинг в более позднее время увеличивается? Рефакторинг не должен занимать много времени, когда это делается чаще.

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


1
«Как объяснить своему боссу, что вы потратите несколько дней на написание кода, который ничего не добавляет к продукту, сложен, и это совершенно другой вопрос». Хорошая попытка ;-) К ​​сожалению, в реальной жизни нам тоже нужно это решить. Поэтому практичнее идти небольшими шагами. Полчаса рефакторинга может быть выполнено как часть двухчасовой задачи, и вашему менеджеру даже не нужно об этом знать. OTOH два полных дня, проведенных на рефакторинг, редко остаются незамеченными.
Петер Тёрёк

@ Петер Тёрёк: Я немного обновил пост. Конечно, у вас все еще есть ситуации в реальном мире, когда вам не разрешают тратить время на рефакторинг. Но я твердо верю, что в теории это всегда выиграл время. (если вы не знаете, код, над которым вы работаете, больше не будет поддерживаться в ближайшем будущем)
Стивен Джеурис

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

1
Рефакторинг, который удаляет дублированный код, не всегда хорош; Возможно, что два метода могут быть идентичны в соответствии с сегодняшними бизнес-правилами, но не завтра. Например, AcmeLockerBankодин может иметь getRow(int itemIndex)метод, который возвращает, index % 5а другой может иметь AcmeButtonPanelидентичный метод, потому что и шкафчик, и панели кнопок нумеруют вещи одинаково; если ни один из сегодняшних банков шкафчиков не имеет элементов с индексом более 1000, но некоторые панели кнопок имеют, и будущие шкафчики используют другой интервал между рядами для индексов в диапазоне 1000-1999 ...
суперкат

1
... добавление дополнительного поведения к банкам-блокировщикам будет легко, если у банков-блокировщиков и банков кнопок есть разные getRowметоды, но может быть более сложным, если функции были объединены в общий метод.
суперкат

0

Разве вы не можете создать новый Интерфейс / Классы, который работает как Фасад поверх старого кода, при этом вводя новый код в своем собственном стиле, который можно легко расширить?


0

Делай это правильно, идя вперед. Используйте функции вместо вырезания и вставки. Это не требует рефакторинга, но дает вам основу для будущего рефакторинга.


0

Вы, как разработчик, предпочитаете поддерживать простой тупой скучный код ИЛИ иметь помощников, которые будут делать глупый скучный код у вас?

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

Постер ответил на свой вопрос, не внося больших изменений прямо сейчас. Хороший выбор. У меня есть проблемы с высокомерием разработчика, что они знают, что лучше для бизнеса. Большой рефакторинг потихоньку ... потому что ты знаешь лучше, чем твой босс? Любой способный менеджер может взвесить выгоду.

Если рефакторинг не вариант, вопрос становится скорее обсуждением правильного времени, места и т. Д. Для этого. Последовательность очень важна. И все же долгоживущий код часто выигрывает от «обновления». Другие обсуждали это ...

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.