Подтвердить что ты не робот

Когда хорошо (если вообще когда-либо) отказаться от производственного кода и начать все заново?

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

  • Злоупотребление потоками: QueueUserWorkItem и потоки в целом используются много, а делегаты пула потоков имеют неинформативные имена, такие как PoolStart и PoolStart2. Существует также отсутствие надлежащей синхронизации между потоками, в частности доступ к объектам пользовательского интерфейса для потоков, отличных от потока пользовательского интерфейса.

  • Магические числа и магические строки. В коде определены некоторые Const и Enum, но большая часть кода использует литеральные значения.

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

  • Предупреждения компилятора. Основной файл решения содержит более 500 предупреждений, а общее число неизвестно мне. Я получил предупреждение от Visual Studio, что он не может отображать больше предупреждений.

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

  • Not Invented Here. Продукт дублирует функциональные возможности, которые уже существуют в общих библиотеках, используемых другими продуктами, например, помощники доступа к данным, помощники по протоколированию ошибок и помощники пользовательского интерфейса.

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

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

EDIT. Чтобы немного уточнить, у нас есть оригинальные требования к проекту, поэтому запуск может быть вариантом. Еще один способ рассказать о моем вопросе: может ли код когда-либо достигать точки, где стоимость его поддержания станет больше, чем затраты на ее сброс и начало?

4b9b3361

Ответ 1

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

Есть много недостатков, о которых следует опасаться.

  • Режимы останавливают появление новых функций от холода в течение месяцев/лет. Немногие, если какие-либо компании могут позволить себе стоять надолго.
  • Большинство графиков разработки трудно подделать. Это переписывание не будет исключением. Упростите предыдущую точку, теперь, задержка в развитии.
  • Ошибки, которые были исправлены в существующей кодовой базе через болезненный опыт, будут повторно введены. Joel Spolsky имеет больше примеров в этой статье.
  • Опасность падения жертвы Эффект второй системы - вкратце: "Люди, которые разработали что-то только один раз, прежде чем попытаться сделать все, что они" не делали в последний раз ", загружая проект со всеми вещами, которые они откладывают при создании версии один, даже если большинство из них должно быть отложено и в версии 2."
  • Как только это дорогое, обременительное переписывание завершено, самая следующая команда, наследующая новую кодовую базу, скорее всего, будет использовать те же самые оправдания для повторного переписывания. Программисты ненавидят изучение другого кода. Никто не пишет совершенный код, потому что совершенство настолько субъективно. Найдите мне приложение реального мира, и я могу дать вам обвинительное заключение и обоснование для того, чтобы сделать переписку с нуля.

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

Ответ 2

На самом деле нужно ломать и начинать?

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

Я уверен, что кто-то теперь свяжет статью Джоэля о том, как Netscape выбрасывает свой код и как он о-ужас и огромная ошибка. Я не хочу говорить об этом подробно, но если вы связали эту статью, прежде чем вы это сделаете, подумайте об этом: движке IE, движке, позволяющем MS быстро выпускать IE 4, 5, 5.5 и 6 преемственность, движок IE, полностью уничтоживший Netscape... он был новым. Trident был новым двигателем после того, как они выбросили двигатель IE 3, потому что он не обеспечил подходящую основу для их будущих разработок. MS сделала то, что Джоэл говорит, что вы никогда не должны этого делать, и потому, что MS сделала так, что у них был браузер, который позволил им полностью затмить Netscape. Поэтому, пожалуйста... просто размышляйте над этой мыслью, прежде чем связывать Джоэла и сказать: "О, вы никогда не должны этого делать, это страшная идея".

Ответ 3

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

Будьте очень осторожны с этим:

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

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

Ответ 4

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

Мысль о том, что до сих пор вы можете исправлять только код кода; за какой-то момент это ускользнет.

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

Ответ 5

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

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

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

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

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

Ответ 6

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

  • У вас уже есть клиенты, использующие его. Они знакомы с ним и могут создать вокруг себя некоторые из своих собственных активов. (Другие системы, которые взаимодействуют с ним, продукты, основанные на нем, процессы, которые они должны были бы изменить, сотрудники, которых они, возможно, придется переучивать). Все это стоит денег клиентов.
  • Повторная запись может стоить меньше в долгосрочной перспективе, чем вносить трудные изменения и исправления. Но вы не можете количественно оценить это, пока ваше приложение не будет более сложным, чем Hello World. И переписывание означает повторный тест и повторное развертывание и, вероятно, путь обновления для ваших клиентов.
  • Кто говорит, что переписывать будет лучше? Можете ли вы честно сказать, что ваша фирма сейчас написала яркий код? Были ли исправлены методы, которые изменили исходный код на спагетти? (Даже если главный виновник был единственным разработчиком, где были его сверстники и руководство, обеспечивая качество посредством обзоров, тестирования и т.д.?)

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

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

Ответ 7

Два потока мысли на этот: у вас есть оригинальные требования? У вас есть уверенность в том, что исходные требования являются точными? Как насчет планов тестирования или модульных тестов? Если у вас есть такие вещи, это может быть проще.

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

Ответ 8

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

Ответ 9

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

Но, на основе codereview, не звучит, как будто бы были какие-то чистые границы.

Ответ 10

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

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

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

Ответ 11

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

Ответ 12

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

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

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

Ответ 13

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

Ответ 14

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

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

Помните, что переписать инвестиции только один раз. Возврат инвестиций в переписывание длится вечно. навсегда.

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

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

  • "Получим ли мы больше пользы от того, чтобы отбросить нежелательный и нестабильный хлам?"

  • "Будем ли мы получать больше пользы, если мы это понимаем, а не документированием, а заменяя что-то, что мы создали как команда?"

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

  • "Разрушено?" И когда вы говорите: "Это не разбилось как таковое", они скажут: "Это не сломалось - не исправляйте".

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

Каков ваш ответ на них?

Это только первое препятствие. Здесь самая худшая ситуация. Это не всегда происходит, но это происходит с тревожной частотой.

У кого-то в вашей пищевой еде будет такая мысль:

  • "Переписывание не создает достаточного значения. Вместо того, чтобы просто переписывать, разрешите его расширять". Обоснование заключается в том, что, создавая достаточную ценность, пользователи с большей вероятностью будут покупать их для перезаписи.

Проект, расширяющий область действия - искусственно - для добавления ценности обычно обречен.

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

Ответ 15

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

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

Ответ 16

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

Ответ 17

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

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

Ответ 18

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

В прошлом, когда сопровождающий получил новый код для поддержки, Правило большого пальца: "Если вам нужно изменить более 40 процентов кого-то иначе код, вы выбросите его и начните сначала". Индекс работоспособности [MI], приведенный здесь, дает гораздо больше количественный метод для определения того, когда "выбросить и начать все". Эта работа была спонсирована U.S. Air Force Information Warfare Center и Министерство энергетики США [DOE], Полевое отделение Айдахо, Договор № DOE ДЕ-AC07-94ID13223.)

Ответ 19

Я думаю, что это правило было...

  • Первая версия всегда выбрасывается.

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

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

Ответ 20

Когда хорошо (если вообще когда-либо) отказаться от производственного кода и начать?

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

Ответ 21

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

Ответ 22

Я никогда полностью не выбрасывал код. Даже при переходе от системы foxpro к системе С#.

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

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

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

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

Ответ 23

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

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

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

Ответ 24

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

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

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

Ответ 25

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

Не тратьте время, если приложение не нуждается в изменениях. Однако, если он не работает так, как вам нужно, и вам нужно контролировать часы и время, потраченные на исправление, отменить его и переписать на стандарты, которые может поддерживать ваша команда. Там нет ничего хуже ужасного кода, который вы должны поддерживать/расшифровывать, но все еще должны жить. Помните, Мерфи Закон говорит, что будет 10 в ночное время, когда вам придется что-то делать, и это никогда не бывает продуктивным.

Ответ 26

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

Ответ 27

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

Ответ 28

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

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

Ответ 29

Раньше я верил в просто переписывание с нуля, но это неправильно.

http://www.joelonsoftware.com/articles/fog0000000069.html

Изменил мой разум.

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