Как оценить, стоит ли обновлять устаревший код
Меня зовут Александр Рябцев, я работаю на позиции Back-end Lead в компании Django Stars, и в этой статье мы поговорим о том, когда необходимы обновления и как их сделать, не влияя на функциональность приложения. Это особенно важно в финтехе, поскольку технологии и навыки пользователей продолжают развиваться. И по мере того, как это происходит, пользователи становятся более требовательными и хотят больше функций, таких как лучшая безопасность или возможность проводить платежи онлайн.
Допустим, клиент планирует добавить биллинг в свою платформу онлайн-кредитования. В подобных случаях разработчики могут решить, что им необходимо обновить код приложения. В конце концов, могут подумать, зачем еще заказчику хотеть обновлять идеально работающий код? И клиент может подумать, что добавление пары функций не имеет ничего общего с обновлением кода и что разработчики просто хотят заработать больше денег. Однако правда в том, что решение специалистов основано на тщательном анализе кода и бизнес-логике.
Что такое обновление устаревшего кода и как это сделать
Что означает «устаревший код»? Это существующий код продукта, уже работающий или только что завершенный, но еще не запущенный, который необходимо каким-то образом финализировать. Когда у компании есть приложение, требующее дополнительных функций, или когда код почти готов, но команда разработчиков не смогла его завершить, это значит, что пришло время обновить устаревший код.
Как вы понимаете, разработчики не могут просто вставить функцию поверх кода, поскольку все в нем взаимосвязано. На это изменение повлияет множество факторов. А поскольку весь код уникален, нет единого рецепта, как это сделать. Когда клиент запрашивает обновление кода продукта, он может вскоре обнаружить, что код не позволяет это сделать из-за слабой архитектуры, его низкого качества или недостаточного покрытия тестами. Вот почему всякий раз, когда человек отправляет такой тип запроса, первое, что делает группа разработчиков, — проверяет код. Как только они получат результаты, предложат сценарий, который лучше всего подходит для приложения.
Критерии оценки для обновления устаревшего кода
Прежде чем разработчики решают изменить код, они разбираются, с чем имеют дело. Например, за почти восемь лет работы в сфере финансовых технологий мы сформировали критерии оценки проектов, чтобы определить потенциальный уровень сложности. Таким образом мы знаем, что делать, если кто-то приходит и просит создать умный калькулятор для платформы онлайн-кредитования или добавить смайлик в правом нижнем углу интерфейса, и какое решение предложить бизнесу. Вот возможные сценарии:
1. Разработчики не принимают участие в проекте, когда видят, что домен приложения слишком сложен и неясен. Вполне возможно, что добавление к нему потребует слишком много ресурсов без эквивалентных выгод для их компании. Это может произойти, если исходный код был написан плохо и убирать чужой беспорядок просто не стоит. Или если запрос нереалистичен. Например, переписать все программное обеспечение для фондового рынка с нуля — возможно, вам стоит переосмыслить свой запрос.
2. Разработчики пишут код с нуля — в некоторых случаях команды инженеров вообще не работают с уже существующей базой кода. Они могут использовать старый код, чтобы понять бизнес-логику продукта или проанализировать функциональность, которая была запланирована, но не была добавлена. Это позволяет им избегать тех же ошибок, что и предыдущие разработчики.
Самое большое преимущество такого подхода — то, что мы можем гарантировать четкую и гладкую структуру конечного продукта. На этом этапе иногда трудно понять, почему старый код больше не соответствует требованиям, но поговорить об этом стоит со своим техническим партнером и обсудить все плюсы и минусы. Часто начать с нуля — более быстрое решение, которое сэкономит заказчику гораздо больше денег.
Приведу пример: однажды клиент попросил обновить код, который он сам начал писать много лет назад, прежде чем передал его кому-то другому. Но в нем было по крайней мере 20 мест, которые необходимо было обновить, прежде чем в код можно будет добавить новую логику и / или функции. А при таком большом количестве обновлений можно легко повредить часть кода, изменив что-то в одной из этих 20. Но, если бы мы написали собственный код в соответствии со спецификацией клиента, но с более прозрачной архитектурой, была бы только одна, максимум две части, которые потребовали бы дополнительной работы.
3. Девелоперы работают с базой кода клиента, добавляя желаемые функции при обновлении (рефакторинге) старого кода шаг за шагом, часть за частью. Это возможно только в том случае, если структура кода ясна и логична, а также полностью протестирована. Но в любом случае клиент должен полностью обсудить это со своей командой разработчиков.
На этом этапе важно понимать, что рефакторинг — жизненно важная часть сопровождения кода и, по сути, жизненного цикла любого продукта. По этой же причине клиент должен предоставить разработчикам достаточно документации.
Как вы понимаете, этот сценарий более требователен, чем сценарий № 2, когда пишется код с нуля. Не потому, что разработчики не знают используемую технологию или не понимают код. Код — это все о видении тех, кто его пишет, и об архитектуре. Работа над унаследованным кодом, написанным кем-то другим, может быть трудной, поскольку его логика, скорее всего, будет отличаться от вашей. Вот почему клиент должен согласиться с тем, что, когда разработчики занимаются чужим кодом, они не могут гарантировать такое же высокое качество, как когда они работают с собственным.
Однако, возможно, что команда специалистов сможет структурировать старый код, если есть механизм, который работает должным образом. В этом случае им не нужно изменять или переписывать эту часть кода. Нужно только знать, какой формат должны иметь входящие данные, а еще формат исходных данных.
4. В самых редких случаях можно продолжить работу со старой кодовой базой, просто добавив новые функции. Это возможно только тогда, когда код настолько безупречно написан и продуман, что вообще не нужно ничего менять. Однако с нами такого никогда не случалось, так как у каждого свое видение архитектуры.
От чего зависят обновления кода
Если вы наконец решите начать обновление кода, существует несколько факторов, которые определяют, в какой степени он должен быть изменен и насколько важны эти изменения. Это возраст, архитектура кода, охват тестированием и развертывание.
- Возраст. Очень важно, имеет ли код возраст один год или пять. Например, вы должны понимать, что пять лет в Python и Django (технологии, с которой мы работаем) — это далекая галактика. За это время многое изменилось, и код, скорее всего, будет иметь огромные дыры в системе безопасности и так далее. Некоторые части кода будут слишком старыми для перехода на новую версию — их будет легче переписать.
- Архитектура кода. Монолитный или микросервисный? Если разработчики могут разделить приложение на части (например, CRM, CMS, веб-сайт и файловое хранилище), они могут и обновлять его по частям. Но если нет видимых частей, остается единственный вариант — переписать код. Обычно, если невозможно разделить код на части, он написан плохо, и его рефакторинг будет сложной задачей.
- Тестовое покрытие. Это определяет, покрыт ли код тестами должным образом (и какие именно тесты) или команде нужно их написать.
- Развертывание. Команда проверит, как проходит развертывание, когда новый код входит в старую систему.
До обновления устаревшего кода: список дел
Мы рассмотрели все технические аспекты, но есть также некоторые управленческие проблемы, которые необходимо решить, прежде чем начинать обновление. Список дел невелик.
Соглашайтесь на ожидания
Клиенту лучше всего составить список того, чего он ждет от приложения, желаемых изменений и целей, которых хочет достичь. Он и его техническая команда должны понимать, что собираются делать.
Определите риски
Чтобы не потерять данные (и, следовательно, клиента), убедитесь, что команда определяет, как приложение будет работать во время обновления и как будет осуществляться переход от старого кода к новому. Например, в нашей практике программирования на Python мы однажды создали прокси, который переключал пользователей на старую или новую базу кода в зависимости от их запросов и текущего этапа обновления.
В других случаях приходилось переносить большую информационную базу пользователей, поэтому мы создали посреднический скрипт, который помог одного за другим переводить их со старой версии на новую. Таким образом мы проверили, как работает передача, и убедились, что никакая информация не потеряна. Но учтите, что для каждого продукта потребуется индивидуальное решение.
Одна из причин этого — разные риски, характерные для разных случаев (например, плохая структура базы данных снижает скорость работы).
Обеспечьте достаточное покрытие тестами
Если тестового покрытия достаточно — отлично. Если покрытие тестами отсутствует, следует сначала написать тесты. И только тогда вы напишете реализацию. Это то, что нужно решить, прежде чем команда приступит к работе.
В то же время специалистам надо определиться, какие тесты они будут использовать. Для наглядности существуют модульные и интеграционные тесты. Модульные тесты — это те, которые используем для одной функции, в то время как интеграционные тесты более трудоемки и проверяют, как разные элементы работают вместе. Опытная команда выяснит, есть ли какие-либо подходящие тесты в старой кодовой базе. Если они используют старый тест для новой функции, и тот проходит успешно, это доказывает, что конкретное обновление безупречно интегрировано в старую базу кода и все работает нормально.
Теперь мы рассмотрели обновление устаревшего кода со всех возможных сторон. Мы выяснили, что это такое и как работает, что нужно сделать для плавного и успешного обновления. Во-первых, разработчики оценивают, с чем нужно работать и могут ли они вообще с этим работать. Затем проверяют возраст кода, его архитектуру и тестовое покрытие, что определяет дальнейшие шаги. И как только клиент скоординирует свои цели и ожидания от проекта со своей командой, вы определитесь с потоком передачи и обеспечите достаточное покрытие тестами, все готово.
Моя первая и главная мотивация при написании этой статьи заключалась в том, чтобы помочь устранить любые недоразумения между компаниями и командами, предоставляющими услуги веб-разработки. Благодаря многолетнему опыту мы с командой убедились, что это может происходить там, где мы меньше всего ожидаем.