К книге
Антихрупкость в ITРаздел II. IT-архитектура для достижения бизнес-целей. Глава 5. Работа с унаследованным кодом. Стратегия изменения
77%
Раздел II. IT-архитектура для достижения бизнес-целей. Глава 5. Работа с унаследованным кодом. Стратегия изменения
115

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

Набор конкретных тактик и стратегий замены унаследованных систем уже описан в книгах:

1. Мартин Фаулер. Рефакторинг. Улучшение существующего кода при тестировании.

2. Джошуа Кериевски. Рефакторинг с использованием шаблонов.

3. Майкл К. Физерс. Эффективная работа с унаследованным кодом.

В этих книгах разобраны конкретные примеры и даны ответы на вопросы про улучшение кода и его покрытие тестами. Например, что делать с длинным методом, который сложно тестировать? Как разорвать ненужные зависимости? Как убрать зависимость от статического класса? И многое-многое другое. Рекомендую прочитать эти книги, тогда 90% проблем в коде не будут для вас проблемой; вы и ваши инженеры разберётесь с тактическим уровнем работы.

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

1. Переписать

Вы смотрите на чужой код и дизайн и видите в них множество недочётов. Хочется просто написать правильно с нуля. Почему бы и нет? Один из возможных вариантов развития старой системы – это её перерождение в greenfield-проекте.

Плюсы:

1. Проанализировав унаследованный код, мы узнаем, как не надо делать.

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

3. Повышенная мотивация в команде, так как кодовая база будет полностью вашей.

Минусы:

1. Бизнес оплатит создание той же системы во второй раз.

2. Заказчик долго не увидит разницы между тем, что было и как стало. Первый релиз новой системы, который превзойдёт старую по количеству фич, появится нескоро.

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

4. Вам придётся поддерживать одновременно и старую и новую системы, пока все пользователи не перейдут на новую.

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

Рекомендация, когда стоит браться за переписывание всей системы с нуля:

1. Заказчик даёт время и деньги на переписывание старой системы с нуля, а вы, со своей стороны, уверены в своих силах.

2. Систему ещё не начали использовать; возможно, она представляет из себя прототип или proof of concept.

3. Система действительно не работает, пользователи отказываются от неё. Например, у меня был проект, который предыдущая команда писала год[93], но в итоге он просто не соответствовал заявленным характеристикам. Дописывать или рефакторить его не было смысла. Мы проанализировали недочёты и реализовали с учётом предыдущих ошибок новую версию с нуля.

2. Оставляем как было

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

Плюсы:

1. Работа над системой не останавливается, клиент видит результаты своих вложений.

2. Поставка новых функций и исправление ошибок идёт с самого начала вашей работы.

Минусы:

1. Если код в системе плохой, то вы продолжите добавлять в него ещё больше костылей, увеличивая техдолг (см. раздел II, глава 6).

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

3. Реанимация системы в разы сложнее, чем создание новой. Для этой работы нужна высокая квалификация, а значит, нужно больше вкладываться в поиск и удержание крутых инженеров. Здесь вы столкнётесь с противоречием: крутые инженеры не хотят копаться в плохом коде, поэтому вопрос с мотивацией окажется очень сложным.

Рекомендация, когда стоит оставить всё как есть:

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

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

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

3. Душитель

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

Метафора этого подхода была описана у М. Фаулера в статье «Strangler Application»[94].

Плюсы:

1. Все плюсы первого подхода с полным переписыванием.

2. Работа старой системы не останавливается, и при этом мы добавляем новые функции.

3. Бизнес сразу начинает видеть результаты своих вложений.

Минусы:

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

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

3. При сложной и запутанной архитектуре унаследованной системы этот подход может быть трудно реализуем.

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

Рекомендация, когда стоит «душить»:

1. Унаследованная система стабильно работает.

2. В основном надо добавлять новые функции, а не расширять уже существующие.

4. Переработка по модулям

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

Плюсы:

1. Постепенное улучшение качества системы.

2. Возможность сделать постоянную скорость поставки (не максимально высокую, но стабильную).

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

Минусы:

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

2. Не всегда возможно выделить модули.

Рекомендация, когда стоит постепенно переписывать по модулям:

1. Унаследованная система имеет высокую ценность для бизнеса.

2. В системе реализовано много отлаженных модулей.

3. В основном надо расширять уже существующие функции.

Предыдущая главаГлава 115 из 149Следующая глава