Практические советы разработчикам, как работать с легаси-кодом | robot_dreams
Для отслеживания статуса заказа — авторизируйтесь
Введите код, который был выслан на почту Введите код с SMS, который был выслан на номер
 
Код действителен в течение 5 минут Код с sms действителен в течение 5 минут
Вы уверены, что хотите выйти?
Сеанс завершен
На главную
Не приговор, а вызов. Как работать с легаси-кодом — практические советы разработчикам

Не приговор, а вызов. Как работать с легаси-кодом — практические советы разработчикам

Рассказывают Павел Попов и Александр Квасенко, PHP-разработчики из команды NIX

Легаси-код — не обязательно плохо написанный код. Им может быть и недавно созданный код на основе современных технологий. Хотя в основном с легаси приходится иметь дело, заходя в старый проект. Его бывает трудно читать, поддерживать и изменять. Возникает немало проблем для всей команды. Разработчикам приходится тратить много усилий на поиск решений, переписывать части кода, вводить дополнительные проверки. Бизнес теряет в динамике развития проекта, тратит ресурсы на обслуживание продукта и добавление новых фич...

Но не все так плохо.

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

Павел Попов (слева) и Александр Квасенко (справа), PHP-разработчики из команды NIX

Как понять, что легаси-код нуждается в изменениях

Выявить проблемы на уровне бизнеса

Когда приложение мешает достигать нужной клиенту цели, легаси нужно заменять как можно скорее. Здесь следует смотреть шире, не только на базовые KPI. Сугубо технические проблемы, о которых расскажут только разработчики, тоже приводят к финансовым потерям. Например, если написание функционала требует много времени из-за «распутывания» наслоений старого кода. Или же если архитектура затрудняет масштабирование или адаптацию продукта к современным требованиям.

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

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

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

Определить соответствие кода текущим задачам проекта

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

Работа с легаси-кодом: какие знания и навыки необходимы

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

Но не обойтись без практического опыта рефакторинга. Иначе не получится выбрать действительно хороший путь для обновления кода.

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

Навыки рефакторинга важны и по другим причинам:

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

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

Как обновить легаси-код: основные шаги

1. Анализ кода

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

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

Конечно, вы еще и будете иметь целостную картину. Например, если обновление требует более 80 % кода, то здесь лучше написать все с нуля. Аналогичная ситуация — когда надо изменить не просто фреймворк, а версию языка, инфраструктурные элементы или экосистему. Часто это требует капитальной перестройки проекта.

2. Создание роадмап

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

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

3. Рефакторинг

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

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

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

4. Тестирование

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

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

Никаких специфических проверок, набор стандартный:

  • юнит-тесты;
  • интеграционные тесты;
  • функциональные;
  • нагрузочное тестирование.

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

Рефакторинг не должен «застопорить» развитие проекта

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

Делайте небольшие итерационные изменения

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

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

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

Работайте над обновлением кода параллельно с основным проектом

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

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

Создавайте новую систему

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

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

Как документировать обновление легаси-кода

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

  • Пишите понятный код. Качественный код не нуждается в комментариях — в нем все и так понятно. Сегодня некоторые могут считать комментарии в коде олдскулом. Однако при желании можете добавлять их. Это точно не помешает новым разработчикам.
  • Ведите документацию. Это может быть техническая, функциональная и другие виды документации или гайдов. Их можно дополнять схемами или диаграммами для объяснения отдельных зависимостей между частями кода.
  • Фиксируйте и подробно описывайте в комитах каждое изменение в легаси: что и почему модифицируете, почему именно так и т. д. Нельзя допускать, когда что-то описано в Jira, а что-то — только в документации.
  • Описывайте не только новый код. В идеале надо вести документацию для всех фрагментов легаси, которые вы обновляете. Даже первичная документация станет полезной при работе над новыми фичами или в дальнейшей поддержке проекта.

Чек-лист оценки успешности рефакторинга

#1 Стабильная функциональность

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

#2 Выдержанные сроки

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

#3 Положительные отзывы

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

#4 Ускорение разработки

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

#5 Улучшение продукта

Здесь традиционные KPI: стабильность, скорость загрузки контента или отклика на запрос, уровень безопасности. Как минимум, эти показатели должны быть не хуже, чем до обновления. А в идеале — стать лучше.

Как не создать новый легаси

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

  • Думайте стратегически. Вы должны создать архитектуру со стабильным фундаментом для дальнейшего развития проекта. С другой стороны — стараться смотреть в будущее и видеть возможные пути развития продукта. Этот подход поможет заложить основу для добавления необходимого функционала. Если этого не сделать, то при изменении требований или для новых фич могут понадобиться какие-то «‎костыли».
  • Выбирайте долговременные решения. Это позволит дольше сохранить технологическую актуальность проекта. Учитывайте популярность фреймворка, частоту обновлений, активность сообщества, которое им пользуется, количество связанных библиотек, качество документации и т. д. Даже если разработчик такого решения вдруг остановит свою работу, фреймворк по инерции будет жить достаточно долго.
  • Соблюдайте правила программирования. По классике: пишите чистый и понятный код по принципам SOLID, следуйте правилам работы на вашем проекте, ведите документацию, внедряйте систему тестов и мониторинга. А еще не забывайте следить за техническим долгом. Иначе количество проблем быстро растет и словно снежный ком разрушает слаженную работу.
  • Настройте систему код ревью. Так вы будете видеть, в правильном ли направлении «распутываете» легаси, становится ли код понятнее, четче, действительно ли ваша работа помогает другим девелоперам.

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

Ещё статьи
Экспертки о том, как оценивают кандидатов на нетехнических интервью
Часть 2. Работа с записями: вставка, чтение, изменение и удаление