Когда большой переписать ответ?


278

Просто прочитайте вопрос о Больших Переписываниях, и я вспомнил вопрос, на который я так хотел ответить.

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

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

TL; DR Когда большой переписать ответ и какие аргументы вы можете использовать, чтобы поддержать его?



6
Он старый, но это классика - «То, чего никогда не следует делать, часть I» Джоэла joelonsoftware.com/articles/fog0000000069.html
Моуг

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

Ответы:


325

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

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

  • Время запуска разработчиков очень велико. Если для запуска нового разработчика требуется больше времени, чем указано ниже (по уровню опыта), то систему необходимо перепроектировать. Под временем наращивания я подразумеваю период времени, в течение которого новый разработчик готов выполнить свою первую фиксацию (для небольшой функции).
    • Только что закончили колледж - 1,5 месяца
    • Все еще зеленый, но работал над другими проектами раньше - 1 месяц
    • Средний уровень - 2 недели
    • Опытный - 1 неделя
    • Старший уровень - 1 день
  • Развертывание не может быть автоматизировано из-за сложности существующей архитектуры
  • Даже простые исправления ошибок занимают слишком много времени из-за сложности существующего кода
  • Новые функции занимают слишком много времени и стоят слишком дорого из-за взаимозависимости базы кода (новые функции не могут быть изолированы и, следовательно, влияют на существующие функции)
  • Формальный цикл тестирования занимает слишком много времени из-за взаимозависимости существующей кодовой базы.
  • Слишком много вариантов использования выполняются на слишком немногих экранах. Это вызывает проблемы с обучением для пользователей и разработчиков.
  • Технология, которой пользуется нынешняя система, требует этого
    • Качественных разработчиков с опытом работы с технологиями слишком сложно найти
    • Это устарело (его нельзя обновить для поддержки новых платформ / функций)
    • Существует просто более выразительная технология более высокого уровня
    • Стоимость обслуживания инфраструктуры старой технологии слишком высока

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

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

  • технический
    • Связь компонентов настолько высока, что изменения одного компонента не могут быть изолированы от других компонентов. Редизайн одного компонента приводит к каскаду изменений не только для смежных компонентов, но и косвенно для всех компонентов.
    • Технологический стек настолько сложен, что проектирование будущего состояния требует многократных изменений инфраструктуры. Это также необходимо для полного переписывания, но если оно требуется для поэтапного редизайна, вы потеряете это преимущество.
    • Редизайн компонента приводит к полной переписке этого компонента в любом случае, потому что существующий дизайн настолько изящен, что не стоит ничего экономить. Опять же, вы теряете преимущество, если это так.
  • политическая
    • Спонсоры не могут понять, что постепенный редизайн требует долгосрочной приверженности проекту. Неизбежно, большинство организаций теряют аппетит к продолжающему истощению бюджета, которое создает постепенный редизайн. Эта потеря аппетита также неизбежна для переписывания, но спонсоры будут более склонны продолжать, потому что они не хотят быть разделенными между частично полной новой системой и частично устаревшей старой системой.
    • Пользователи системы слишком привязаны к своим «текущим экранам». Если это так, у вас не будет лицензии для улучшения жизненно важной части системы (интерфейс). Редизайн позволяет обойти эту проблему, поскольку они начинают с чего-то нового. Они по-прежнему будут настаивать на получении «тех же экранов», но у вас есть немного больше боеприпасов, чтобы отодвинуться назад.

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

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

Некоторые стратегии успеха:

  • Однако, если вы это сделаете, не пытайтесь конвертировать существующий код. Дизайн системы с нуля. Иначе ты зря тратишь время. Я никогда не видел и не слышал о «конверсионном» проекте, который не закончился бы с треском.
  • Перенесите пользователей в новую систему по одной команде за раз. Определите команды, которые испытывают НАИБОЛЕЕ боль в существующей системе, и сначала перенесите их. Пусть они распространяют хорошие новости из уст в уста. Таким образом, ваша новая система будет продаваться изнутри.
  • Создайте свой каркас, как вам нужно. Не начинайте с того, что я потратил 6 месяцев на создание фреймворка, который никогда не видел реального кода.
  • Держите ваш технологический стек как можно меньше. Не переусердствуйте. Вы можете добавлять технологии по мере необходимости, но сложно их использовать. Кроме того, чем больше у вас слоев, тем больше работы нужно выполнять разработчикам. Не усложняйте с самого начала.
  • Вовлекайте пользователей непосредственно в процесс проектирования, но не позволяйте им диктовать, как это сделать. Заработайте их доверие, показав им, что вы можете дать им то, что они хотят лучше, если вы будете следовать хорошим принципам дизайна.

25
Я думаю, что Джоэл считает, что при переписывании вы теряете знания, накопленные в старом коде.
Quant_Dev

14
@quant_dev отчасти да, но когда вы переписываете иногда, вы понимаете, что многие ошибки в старой системе были вызваны тем, как работала старая система, а не строго логически связаны с тем, как должна работать идеальная система.
Тьяарт

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

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

11
Это полезный ответ, но далеко не фантастический, потому что он производит неправильное впечатление на некоторые вещи. Например, «Имейте в виду, что общая стоимость повторного определения значения всегда выше, чем полное переопределение» - слово «всегда» в этом предложении является неправильным, поскольку «повторное определение значения» дает вам возможность повторно использовать по крайней мере некоторые части существующего дизайна, в то время как «полное переписывание» не предлагает вам этого. Я знаю это наверняка, потому что я действительно находился в той ситуации, когда мы переписали приложение LOC> 100K частично полностью, частично нет.
Док Браун

109

Я участвовал в двух больших переписываниях. Сначала был небольшой проект. Второй был основным продуктом софтверной компании.

Есть несколько подводных камней:

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

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

Переписать может быть ответом, если:

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

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


11
+1 за подход рефакторинга. Много раз не хватает времени или человеко-часов, чтобы переписать и поддерживать существующую систему.
Райан Хейс

В настоящее время это используется для демонстрационного приложения (ни один покупатель не купил его недавно, и я подумал, что сейчас самое подходящее время для его воссоздания).
Джонн

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

4
Недавно я переписал приложение Visual Basic на Java. Это позволило ему работать как служба под Windows (без Java GUI) - это выгодно для клиента.

4
«Переписывание не имеет прямого эффекта / выгоды для клиента» - это часто миф, поскольку новые платформы предоставляют «встроенные» многие улучшения производительности, которые либо невозможно, либо слишком дороги для реализации. Один из примеров, обновление приложения vb6 до приложения .net позволяет пользователям открывать большие файлы (благодаря 64-битной архитектуре), что означает, что конечным пользователям не нужно искусственно прерывать свою работу.
Стивен

72

Пришло время для переписывания, когда:

Стоимость переписывания приложения + обслуживания переписанного приложения меньше стоимости обслуживания текущей системы с течением времени.

Некоторые факторы, которые делают поддержание текущего более дорогим:

  • Язык настолько стар, что вы должны платить людям, которые знают, что это много денег, чтобы программировать на нем (COBOL).
  • (из опыта, к сожалению) Система работает на аппаратной архитектуре, которая настолько старая, что им приходится искать части Ebay и COLLECT, чтобы добавить к машине, на которой она запущена, потому что они больше не созданы. Это называется «сроком службы оборудования» и стоит дорого, поскольку по мере того, как запасные части становятся все более дефицитными, они (могут) подорожать или они (абсолютно) в конечном итоге закончатся.
  • Это стало настолько сложным, что //Here be dragons.комментарий во всем вашем коде.
  • Вы не можете писать другие проекты и добавлять новые ценности для компании, потому что вы всегда исправляете этого уродливого зверя.

Именно это и подтолкнуло к переписыванию, в котором я участвовал. Код был настолько хрупок, и стоимость добавления новых функций , так высоко, что не переписывать уже не вариант.
Фрэнк Шиарар

16
Я хихикаю здесь о пункте № 2.
Пол Натан

4
@Paul: я тоже сделал, когда клиент сказал мне об этом, потом я узнал, что они серьезны ... и что я буду собирать требования для переписывания. Какой это был захватывающий день!
Райан Хейс

3
Проблема в том, как вы измеряете затраты.

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

17

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

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

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

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


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

1
Согласовано. Часть этого утверждения следует интерпретировать как «рефакторинг» в ваш «новый» проект. То есть, если вы действительно уже пошли по этому радикальному пути. Как уже упоминалось, это крайняя редкость, которую почти никогда не следует делать.
Дэн МакГрат,

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

12

Хотя я согласен с ответом Крамия и мнением Джоэла, бывают случаи, когда уместно сделать переписывание. В долгоживущих приложениях (я говорю о 10-20 лет или более), обслуживание становится все дороже со временем. Это связано с тем, что код становится все более и более спагеттизным, поскольку исходная архитектура жертвуется ради быстрых исправлений. Также разработчики старых технологий становятся все более редкими и дорогими. Наконец, аппаратное обеспечение начинает стареть, и становится все труднее находить новое оборудование, операционные системы, платформы и т. Д. Для запуска старого приложения поверх. Кроме того, бизнес развивается, и, скорее всего, старая система не будет отвечать бизнес-потребностям организации, как это могла бы сделать новая система.

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


+1 за упоминание закона Хофштадтера .
Baelnorn

11

Стоп! Переписывание почти никогда не является ответом. Чаще всего рефакторинг - лучшая ставка.


Конечно, бывают случаи, когда перезапись оправдана:

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

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

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

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

Большие преимущества рефакторинга таковы:

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

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


2
Не могли бы вы расширить этот ответ, объяснив, почему рефакторинг чаще, чем не лучше, чем переписывание? И когда ответ будет переписан?
Габлин

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

10

Может помочь эта графика, она зависит от качества кода и бизнес-ценности приложения:

введите описание изображения здесь

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


4
Зачем инвестировать в переписывание проекта с низкой стоимостью бизнеса? Просто выбрось это!
Йорген Фог

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

8

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

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

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

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


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

7

Я работал в небольшой софтверной компании, у которой было несколько приложений DOS, которые были модернизированы для работы с Y2K, переписаны как 16-битное приложение Windows, а затем полностью переписаны как 32-битное приложение с одной дополнительной «маленькой» функцией (в конечном счете, используемой только один клиент), что повлияло на всю структуру.

Перенос 16-битного кода на 32 мог бы быть выполнен за месяц одним человеком, но NOOOOOOOOO, нам пришлось переписать его, чтобы Soooooooooo намного лучше. Эта вещь может быть адаптирована для других отраслей, будет иметь полные спецификации и псевдо-код, прежде чем они даже начали. Спецификации были созданы, но это заняло так много времени, что даже не было времени, чтобы написать настоящий код. Он был выпущен поздно, с большим количеством ошибок, чем «началось» с 16-битной версией (это было на v.3.0 и, наконец, до такой степени, что мы почти сделали это за неделю, и никто не сообщил о новой ошибке).

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

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


5

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

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

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


5

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

Эта программа asp изобилует такими вещами, как

  • include(close.aspx) который внутри имеет одну строку кода, которая закрывает последнее открытое соединение с базой данных.
  • Устаревший код просто закомментирован случайно
  • Не заботиться о безопасности
  • Код спагетти, тысячи строк. Все в одном файле.
  • Функции и переменные без четкого значения за их именами

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

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

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


4

У Джоэла Спольски есть отличная статья на эту тему: То, чего никогда не следует делать, часть I

Из названия, которое вы можете сказать, это своего рода односторонность (он говорит о том, почему вы никогда не должны бросать код) IMO, в этом много правды, я недавно видел видео на канале 9 на 25-й годовщине Excel, где некоторые разработчики говорили, как даже сегодня, если вы заглянете в исходный код, вы проверите ревизию и в конечном итоге вернетесь к коду, который использовался в Excel и был написан 20 лет назад.

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

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

Мой реальный мир: приложение silverlight, которое я сейчас разрабатываю в версии 0.6, имеет множество асинхронных вызовов, которые делают код настолько запутанным. С тех пор как я обнаружил Reactive Extensions на этой неделе, я действительно хочу переписать большую часть кода, но что теперь я скажу своему клиенту? Программа работает отлично (с некоторыми утечками памяти), но им все равно? Я не могу сказать им, что у меня еще 2-3 недели, потому что я хочу что-то сделать заново. Я, однако, собираюсь разветвить код и переписать / поиграть с ним в свободное время.

Просто мои 2 цента хорошо !?


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

+1 за ветвление. Многие люди говорят «не переписывать», потому что кажется, что вы выбрасываете старый код - но это не так. Вы можете иметь параллельные кодовые базы.
lunchmeat317

Чтобы быть справедливым, если вы человек, который просит Джоэла Спольски за советом, то вам не следует делать полную переписку :-) И в противном случае, вам следует только переписать, если вы можете убедить все заинтересованные стороны, почему аргументы Джоэля не учитываются в вашем конкретном случае.
gnasher729

3

Существующее решение не масштабируется.

Я смотрю на тебя, MS Access.


Я не уверен, что вы смотрите на правильный. Jet Red не предназначался для масштабирования когда-либо, AFAIK.
JensG

как это отвечает на заданный вопрос?
комнат

3

По словам Джоэла, большие изменения - это единственная худшая стратегическая ошибка, которую может совершить компания:

Вещи, которые вы никогда не должны делать, часть I

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

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


5
Да уж. Я искал некоторые контраргументы на это. Это должно быть сделано иногда.
Джонн

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

Joels статья хороша тем, что в ней подробно объясняется, как все может пойти плохо

6
Джоэл использует пример браузера Netscape Navigator. Это потребительский продукт, который был в середине огромной кривой роста, работающей против конкуренции с большим бюджетом. Это была стратегическая ошибка для Netscape. С другой стороны, внутренние заказные «корпоративные» программные проекты отличаются. Вы не спешите на долю рынка. Там нет опасности, что все ваши пользователи перейдут на конкурентоспособный продукт. Это сводится к бизнес-решению: окупится ли стоимость переписывания в долгосрочной перспективе и / или это лучший способ достижения бизнес-целей?
Скотт Уитлок

Я думал, что Джоэл достиг ключевой концепции: «Вы никогда не знаете, какие решения не были задокументированы, что вам придется пройти нелегкий путь»
MathAttack

2

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

Если вы не хотите менять технологию, в коде отсутствует какая-либо структура (я видел это очень давно на каком-то PHP-сайте, автор просто скопировал / вставил spahgetti вместо include / class / function) или вы взяли что-то у другого человека, который очень плохо написано.

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



+1 Мне нравится ваше мнение, хотелось бы узнать ваши мысли о переписывании нового набора API? (См. Мой ответ ниже)
гедеон

Да, это хорошие моменты. Microsoft переписала код winXP, и они даже не смогли получить право на удаление / копирование файлов в первой розничной версии Vista. В то время как когда они только совершенствовали свою кодовую базу, мы постоянно улучшали качество (W3.11 => W95 => W98 => ME => XP), Vista, в которой они переписали много основных частей, была катастрофой. Для нового API ... я бы отделил текущий код, чтобы иметь как можно больше, и использовал бы новый API на более высоком уровне. Например. ваши основные классы остаются такими, какие есть, но интеграция осуществляется с использованием нового API. Если не все так грязно, что ничего не может быть сделано, кроме как начать с 0.
Slawek

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

1
@ JᴀʏMᴇᴇ: Согласен - если вы ничего не узнали и не приобрели опыта при его внедрении в первый раз и / или если вы не можете лучше выполнять работу сейчас, когда у вас больше знаний / опыта / задним числом; тогда ты картошка а не программист.
Брендан

2

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


2

Есть классическая шутка о том, что «если бы я собирался в XI, я бы не начал отсюда».

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

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

  • слишком мало способностей в отделе,

  • слишком мало взносов от клиентов или руководства для дополнительной работы,

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

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


2

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

Вместо этого переписывание часто случается, чтобы облегчить проблемы управления:

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

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

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

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

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


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

1

При переходе на совершенно новую технологию необходимо обеспечить желаемую функциональность.

«Абсолютно новый»: если вы планируете переписать, но использовать ту же платформу, то рефакторинг и разумная реструктуризация почти наверняка являются лучшим решением. Термин «платформа», как он используется здесь, несколько расплывчатый - он может включать в себя язык и, возможно, операционную систему (на ум приходит расширение от Linux до Windows или наоборот), но, вероятно, не каркас (например, замена Struts на Spring).

«Требуется обеспечить желаемую функциональность»: примерно в 2000 году я инициировал проект по переписыванию основного компонента сервера в Java с C ++, чтобы включить готовые потоки, кэш объектов и транзакции, управляемые клиентом. В то время существовало несколько библиотек многопоточности для C ++, которые мы должны были бы поддерживать, и для обеспечения многопоточности большая часть кода нашей базы данных требовала бы почти полного переписывания. Что касается контролируемых клиентом транзакций ... не случится со старой архитектурой.

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


0

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

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


0

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

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

Даже тогда вы хотите ограничить объем вашей переписать. Например, у нас было какое-то устаревшее программное обеспечение в компании, написанное на C ++ с мышлением программиста на C, который не знал о модульности. Конечным результатом был код спегетти в форме конечного автомата, который охватывал несколько классов и библиотек DLL. У нас было новое требование, которое сильно отличалось от предположений, встроенных в код, и собиралось стать частью запатентованной добавочной стоимости компании для ее клиентов.

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

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


0

ОП не указывает на масштабы проекта, но основная подсказка, которую я принял, была «написана на старом [language / dialect] с использованием старых [libs]», которые для меня являются основными драйверами переписывания. Фактически, большинство проектов, в которых я принимал участие в какой-либо значительной долговечности рынка, в конечном итоге осознают, что размещение обновлений для компиляторов / интерпретаторов / операционных систем является важной задачей для поддержки базы кода.

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


0

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

Для почти любого реального сценария, хотя я бы просто рекомендовал рефакторинг на месте. ^ _ ^. Как правило, слишком много скрытых непредвиденных расходов приходится переписывать, когда появляются недокументированные юридические и бизнес-требования, и в последнюю минуту начинаются взломы.

== Рефакторинг на месте для большего блага и прочее ==

Рефакторинг унаследованного кода обычным старым инкрементным подходом,

  1. Если у вас есть возможность конвертировать в UML и задокументировать, какая там небольшая архитектура.
  2. Если вы работаете с системой контроля версий, посмотрите, как генерировать некоторые отчеты об изменении кода, и выясните, какие файлы и разделы файлов были изменены наиболее часто. Запишите их, так как они, вероятно, будут теми областями, с которыми вы захотите разобраться в первую очередь.
  3. Прежде чем изменять какой-либо код, всегда старайтесь добавить некоторые тестовые покрытия (подойдут даже уродливые функциональные тесты с полным стеком). Если вы имеете дело с большой грязной процедурной логикой извлечения кода, вы намереваетесь перейти на какой-то разумно названный метод или функцию и, если возможно, добавить несколько тестовых случаев, которые проверяют ваш новый метод. сделайте любой ужасный хак, который вам нужен, и, если возможно, внесите изменения в параметры, если они обычно подправлены, например, ширина поля или заголовок, так что в следующий раз будет немного проще перейти к обновлению.
  4. Используйте шаблон адаптера и постарайтесь скрыть крошечные биты унаследованного кода под ковриком логически названных классов и методов, так что для выполнения большинства общих задач, которые вы и другие разработчики выполняете, вам не нужно беспокоиться о страшных битах, происходящих позади Вы находитесь за этими милыми чистыми методами и классами, за которыми вы спрятали этот унаследованный код - как те милые семьи, которые держат в сараях уродливых бывших членов семьи зомби-убийц, чтобы они не испортили повседневную жизнь ферма. , , как обычно.
  5. По мере того, как вы продолжаете сокращать и очищать разделы кода, продолжайте увеличивать охват тестами. Теперь вы можете копать еще глубже и «переписывать» еще больше кода, когда это необходимо / желательно с постоянно растущей уверенностью.
  6. Повторите или примените дополнительные методы рефакторинга, чтобы продолжить улучшать свою кодовую базу.

Ветвление по абстракции

  1. Определите проблемную область в коде, который вы хотите удалить (слой постоянства, генератор PDF, механизм подсчета счетов, генератор виджетов и т. Д.).
  2. Запустите (напишите, если необходимо) некоторые функциональные тестовые сценарии (автоматизированные или ручные, но, как вы знаете, автоматизированные) для базы кода, предназначенной для этой функциональности, а также для общего поведения.
  3. Извлечение логики, связанной с этим компонентом, из существующей исходной базы в класс с некоторым разумным интерфейсом.
  4. Убедитесь, что весь код теперь использует новый интерфейс для выполнения действия X, которое ранее было случайным образом распределено по всему коду (Grep базы кода, добавьте трассировку в новый класс и проверьте страницы, которые должны вызывать его, и т. Д.), И что Вы можете контролировать, какая реализация будет использоваться, изменяя один файл. (Реестр объектов, класс фабрики, независимо от того, что IActivityXClass = Settings.AcitivtyXImplementer (););
  5. повторно запустите функциональные тестовые сценарии, которые проверяют, что все еще работает со всеми действиями X, добавленными в ваш новый класс.
  6. По возможности пишите модульные тесты вокруг нового класса-обёртки X деятельности.
  7. реализовать новый класс с менее безумной логикой спагетти, чем унаследованная реализация, которая придерживается того же интерфейса, что и унаследованный класс.
  8. убедитесь, что новый класс проходит модульные тесты, которые вы написали для унаследованного класса.
  9. обновите свой код, изменив реестр / factorymethod / что угодно, чтобы использовать новый класс вместо старого.
  10. убедитесь, что ваши функциональные тесты все еще проходят.

Открытый Закрытый Принцип и Общая Бизнес-логика / Уровень Постоянства

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

  • Как минимум отделить уровень представления от бизнес-уровня и уровня персистентности.
  • внедрить новый пользовательский интерфейс и лучший уровень представления, который использует тот же общий уровень бизнеса и персистентности.
  • Убедитесь, что данные, созданные с новым пользовательским интерфейсом, не разрушают старый пользовательский интерфейс. (вы будете в горячей воде, если пользователи нового инструмента прервут пользователей старого инструмента). Если вы стремитесь к полной обратной совместимости, вы должны сохранять все в одних и тех же постоянных слоях. Если вы просто хотите переадресовать совместимость в новый инструмент, используйте новую базу данных и новые таблицы или таблицы расширений для отслеживания данных, не относящихся к устаревшей системе.
  • Для новых функциональных возможностей и уровня персистентности необходимо добавлять новые таблицы и методы, не изменяя существующую унаследованную логику, или добавлять столбцы, ограничения к существующим таблицам. например, если вам нужно начать отслеживание экстренного контакта работодателя, а некоторые другие поля не изменяют существующую таблицу сотрудников (мы не знаем, какие предположения делают устаревшие данные об этой таблице), добавьте таблицу расширений идентификатор employee_ext, employee_id, emergency_contact_id и т. д.
  • Медленно перенести пользователей на новую систему. если возможно, переведите устаревшую систему в режим только для чтения или просто добавьте предупреждение, сообщающее пользователям, что она больше не будет доступна после даты X.
  • реализовать в новом интерфейсе любые приоритетные функции или бизнес-требования
  • пролонгировать базу пользователей.
  • продолжить очистку бизнес-логики и пользователей уровня персистентности от других методологий рефакторинга.

0

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

Возьмем, например, C #, код v7 пишет намного чище, безопаснее и лаконичнее, чем v2. Такие вещи, как Elvis и оператор объединения нулей, помогают на тонну.

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

Также - встроенные системы Linux ... Подумайте об установке новых инструментов - переключитесь на git из svn или добавить Vi в вашу систему и т. д.

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


-2

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

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

Но на самом деле это не «переписывание» оригинала в том смысле, что вы пытаетесь достичь паритета функций.

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