Должен ли я отказаться от рефакторинга этого и запланировать переписывание?

Мне поручено поддерживать скромно большую систему (~ 60 тыс. LOC не-Moose OO Perl). Я начинаю сомневаться в мудрости рефакторинга, а не переписывать его. Я знаю, что этот вопрос обсуждался подробно, но ситуация необычайно сложна и имеет несколько элементов, которые указывают на противоположные стороны, поэтому мой вопрос. Извините за многословие вопроса; это было настолько кратким, насколько я мог справиться, получив всю картину.

По мере того, как система стоит, абстракции довольно плохи при инкапсулировании чего-либо чисто, о чем свидетельствует частая зависимость от действия на расстоянии, обильное использование блоков if/else с интимным знанием объектов типа, не связанных с модулем под рукой, и график зависимости, который выглядит как социальная сеть. Это, я чувствовал, было плохо, но может быть реорганизовано.

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

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

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

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

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

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

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

Ответ 1

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

Но то, что сработало для меня, может не работать для всех.

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

  • Ваш работодатель видит ценность в переписывании/рефакторе кода?

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

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

  • Как часто будут добавляться новые обновления/функции-запросы в код?

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

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

  • Код должен будет выполнять функцию X через n месяцев. Насколько он способен сегодня?

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

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

  • Сколько времени потребуется для реализации предусмотренных изменений?

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

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

Ответ 2

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

Ответ 3

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

1) Мои самые большие критерии: уже выпущен проект, и мы поддерживаем проект, или мы строим проект, который будет выпущен?

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

2) Сколько времени займет переписывание? Будет ли новый код экономить ваше время на дороге в обслуживании и будущем развитии?

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

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

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

Итак, надеюсь, моя 10 ¢ (2 ¢ + инфляция) помогает. Удачи!