Приветствую всех! На связи Михаил Емельянов, руководитель Android-направления в RuStore.

За последние два года наш проект достиг впечатляющих результатов: более 50 миллионов установок, около 40 тысяч приложений и более 10 тысяч разработчиков.

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

Что такое техдолг

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

В разработке ПО часто встречаются примеры технического долга:

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

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

3. Спагетти-код — это структурированный, но переусложненный код с множеством зависимостей, который трудно поддерживать и развивать. 

Чем страшен долг 

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

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

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

  • 2016 год. В компании Delta Air Lines произошел непредвиденный сбой казалось бы надежных систем бронирования, регистрации на рейс и посадки, что вызвало простой в течение нескольких часов и отмену более 2000 рейсов.

Эволюция в RuStore: от MVP до многомодульного проекта

RuStore начал свой путь в 2022 году как MVP, который был разработан всего за три месяца. Нам удалось быстро настроить основной функционал и привлечь большое количество пользователей. 

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

В 2024 году мы столкнулись с дополнительными сложностями. Несмотря на использование современных технологий Kotlin, Compose, Flow и чистой архитектуры, мы обнаружили множество недочетов и ошибок, связанных с быстрым развертыванием MVP.

Определение приоритетов  

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

Сначала мы определили три ключевых метрики, которые влияют на проект:

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

  2. Time-to-Market (время до выхода до пользователей): Мы стремимся к быстрому выпуску новых решений для пользователей.

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

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

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

  • UI-слой и presentation-слой: Они составляют значительную часть кодовой базы проекта — около 50%. Любые изменения в дизайне или новые требования продукта от дизайнеров требуют обновлений в UI-слое. Эти изменения должны быть быстро реализованы, чтобы не замедлять процесс разработки.

  • Влияние кода проекта на TTM. В частности, нам очень важна была скорость сборки. 

Аудит проекта 

Мы решили в течение 2-4 недель собрать все проблемы по проекту и оформить их в единый шаблон. Этот шаблон включает:

  • Описание проблемы

  • Важность проблемы

  • Причины, по которым необходимо ее исправить

  • Скриншоты и примеры для подтверждения

Создали структурированные и наглядные описания всех выявленных проблем.

Примеры задач.
Примеры задач.

Стратегия управления техническим долгом

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

Для пересмотра и оптимизации различных аспектов проекта мы снова обратились к нашим метрикам Stability, TTM, Scalability.

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

  1. Архитектура проекта. Мы выбрали классический подход MVVM StateFlow для архитектуры, так как он прост в понимании и использовании всеми инженерами нашей команды. Этот подход был выбран для обеспечения понятности и тестируемости архитектуры. Мы также пересмотрели подход к разработке бизнес-логики, внедряя domain-driven design для работы с доменными сущностями и моделями, чтобы упростить взаимодействие между backend-разработчиками, QA, мобильными разработчиками и продуктовыми командами.

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

    Кроме того, мы пересмотрели подход к бизнес-логике, опираясь на наш опыт с Domain-Driven Design, и внедрили его в нашу архитектуру.

  2. Бизнес-логика. Наша система должна точно отражать продукт. Мы работали не просто с полями и типами, а с доменными сущностями и моделями. Это необходимо для того, чтобы backend-разработчики, QA, мобильные разработчики, аналитики и продакт-менеджеры легко понимали друг друга.

    Структура должна быть связана слабыми зависимостями, особенно в core-функционале, таком как flow установки.

  3. Время сборки проекта. Мы стремились к минимальному времени сборки проекта, чтобы ускорить цикл разработки. Мы достигли значительных улучшений благодаря оптимизации Gradle и настройке кэша зависимостей. На данный момент у нас очень хорошие метрики времени сборки, что способствует более эффективной работе команды.

План исправления долга

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

Группировка проблем по факторам и приоритетам

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

  2. Приоритизация задач: Проблемы были приоритезированы от P0 до P3. Особое внимание уделялось проблемам, влияющим на масштабируемость и ключевые аспекты нашего продукта.

  3. Интеграция в планы команд: Технические задачи по устранению долга включались в планы работы команд. Мы интегрировали эти задачи в планинг-рейсы, ориентируясь на цели и ключевые результаты (ОКР) компании.

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

Балансировка бэклога

Сегодня в IT‑индустрии методологии разработки Agile, с использованием фреймфорков «Scrum», «Kanban», часто оказываются неэффективными в условиях быстрого темпа и постоянных релизов — у команд просто нет времени на технические задачи! По этой причине традиционная практика выделения 20% времени на технический долг часто не работает.

Поэтому мы разработали подход "Балансировка бэклога", который позволяет командам самим определять, сколько времени они могут выделить на устранение технического долга, главное дать гарантии на исправление в течение 2-3 месяцев. В данный период времени они могут заполнять бэклог активного плана на 20%, 30%, 40% или даже 60% техническими задачами, в зависимости от нагрузки фич. Этот подход легко интегрируется в планирование команды и понятен, как инженерам, тимлиду, так и продакту.

Преимущества:

  • Гарантированное выполнение задач по устранению технического долга.

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

  • Эффективное планирование и балансирование технических задач в бэклоге, что приносит пользу как бизнесу, так и технической команде.

Убираем последовательно весь собранный техдолг

После построения roadmap мы решили в первом квартале фокусироваться на исправлении проблем с приоритетом до 10 п., во втором и третьем кварталах — до 20 и 30 соответственно. Основной целью этого подхода было не прерывать выполнение работы по устранению технического долга. Мы готовы были продолжать этот процесс в течение 8 месяцев, чтобы остановить нарастание технического долга в проекте.

Итеративно каждый квартал мы фиксили эти проблемы, методично устанавливая приоритеты от 0 до 10, от 10 до 20 и так далее. 

Итоги борьбы с техдолгом в RuStore

За последние три квартала мы добились значительного прогресса в сокращении технического долга в RuStore:

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

  • снизили технические задолженности и продолжили разработку без остановок: современный стек технологий освободил нас от зависимости Google-сервисов, что позволит нам сохранить стабильность работы RuStore в случае блокировок.

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

Советы по управлению техническим долгом

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

  2. Определите ключевые метрики: Разработайте метрики, такие как TTM, стабильность и удовлетворенность клиентов. Эти метрики помогут демонстрировать пользу технических изменений.

  3. Выбирайте стратегии исходя из потребностей вашего проекта: Опирайтесь на инструменты, которые решают ваши задачи и удобны вам.

  4. Устанавливайте приоритеты и не пытайтесь решить всё сразу: Разделите задачи по приоритетам и решайте их по мере поступления. Это поможет поддерживать высокий уровень мотивации и видеть результаты работы над ключевыми задачами.

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

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

Комментарии (5)


  1. xztv
    26.06.2024 09:11
    +1

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

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

    А как быть, или чтобы вы посоветовали, оглядываясь назад, когда идет фаза активного роста и техдолг создается вот прямо сейчас в угоду новых фич и развития проекта?


    1. michaem Автор
      26.06.2024 09:11
      +4

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

      А вот альтернатива с квотам ("20% на техдолг"), увы, эффективно работает, когда процессы разработки настолько зрелые, что по каждой команде считаются емкость (estimates) бэклога за иттерацию. И за счет емкости бэклога понятно сколько это 20% и действительно будут ли они сделаны.

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


  1. danilovmy
    26.06.2024 09:11
    +3

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

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

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


  1. sergeykonshin
    26.06.2024 09:11

    Как это работает с практической точки зрения. Есть команда сотрудников, они пишут код неважно какого качества. Если бизнес разрастается - всё начинает тормозить. Нанимают спецов и архитекторов со ставкой x2 - чтобы те разгребли гуано, которое наспех сколотило предыдущее поколение. Всё покрывается метриками, тестами, анализаторами. Через 3-6-12 месяцев тормозить перестаёт, опытная команда разбегается, из спецов оставляют кого-нить чтобы больше не пускали костыли в код. Со временем всё устаканивается, тут уже на сцену выходят адепты JSDD (Job Safety Driven Development) неявно заражая всех остальных, проходит время, и, если бизнес опять таки каким-то чудом умудряется подрасти - процесс повторяется снова)


  1. 4Lord
    26.06.2024 09:11
    +2

    Я считаю вы большие молодцы, еще лет 40 и вы приблизитесь к уровню PlayMarket