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

Что тут интересного, скажите вы? Любой IT manager, будь то Team Lead, или CTO, в течении своей карьеры встречался с подобного рода задачами и создавал продукт и команду с нуля. 

Но это был отнюдь не ноль. В момент моего прихода уже была устоявшаяся Enterprise архитектура, какая-никакая инфра, “почти” готовые мобильные приложения под Android и iOS, остатки былой команды и сорванные сроки. Оказалось, что “Next Gen” приложение уже разрабатывается не в первый раз, были попытки и до этого, и они все провалились. Многие инженеры и менеджеры, которые с самого начала участвовали в проекте, уже давно покинули его. 

И тогда пришло осознание, что это будет одним из самых сложных и захватывающих проектов за мою (на тот момент 7-летнюю) карьеру работы лидом мобильной разработки…

Глава 1. На остатках былого величия

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

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

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

Что же было по технике?

  • Были текущие мобильные приложения на Android и iOS в сторах с крайне низкой оценкой и внешним видом а-ля “начало 2010-х”, которые разрабатывали ребята-аутсорсеры. Эти приложения и нужно было как можно скорее заменить новыми 

  • Почти готовые приложения для Android и iOS

  • В Android-e: Kotlin, Kotlin Coroutines, Clean Architecture, многомодульность на Dagger 2, MVVM на Flow, своя дизайн-система (на стандартных views, без compose)

  • В iOS-е: Swift, RxSwift, VIPER, многомодульность, дизайн-система (стандартная, без SwiftUI)

  • Отдельная библиотека для Backend Driven UI с ядром, написанным на KMM

  • CI/CD был простым, но все-же был (на основе gitlab) и его можно было развивать

  • Юнит-тестов практически не было

  • Современная микросервисная архитектура, есть служебные сервисы

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

Так, а что было по оргструктуре?

  • Не было как таковых продуктовых команд

  • Существовал отдел (порядком уже поредевший) мобильной разработки iOS и Android в рамках нашего департамента 

  • В департаменте были отделы тестирования и системной аналитики

  • Инфраструктура и devops, а также  регрессионное тестирование - находились за пределами департамента и с ними нужно было отдельно договариваться.

Да, это была “старая-добрая” оргструктура эпохи “развитого waterfall”. В организации, как я понял, только стартовали процессы разделения на бизнес-стримы, но на тот момент это выглядело так:

И самое плохое: не было никакого “демо”. Руководители бизнес-стримов не держали в руках смартфонов с новыми приложениями и не обладали информацией, в каком качестве выходят их фичи и как они выглядят.

Возможно в этом была причина провала предыдущей команды, как мы думали тогда?

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

И мы это сделали. С одной оговоркой. Мы просто показали приложения в самом плохом свете. Что все плохо: дизайн некрасивый, бэкэнд работает медленно и не с первого раза. 

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

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

Но больше всего критиковалась работа Backend Driven UI системы и политика отдела архитектуры, согласно которой, все фронтальные фичи приоритетно должны разрабатываться именно как Backend Driven UI решения на основе WebView (React) или же на основе нативного для iOS и Android генератора форм (КММ + платформенные реализации UI компонентов).

Мои коллеги предложили все делать “чисто на нативе”, без backend driven по максимуму, только REST и раздельный код под iOS и Android, ведь так больше графических возможностей, выше производительность. В конце концов это превратилось в почти как лозунг. 

И это была первая и самая главная ошибка.

Омут памяти 1.

Цель была - сделать все "по уму". Конечно, все описанные выше проблемы имели место быть.

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

С этим как раз не было проблем. Руководство выделило большое количество ставок под найм разработчиков.

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

  • Запускаем активный найм

  • Создаём платформенные команды iOS, Android, Mobile Backend Driven UI

  • Платформенные команды являются центрами компетенций, строят общие сервисы, проводят onbording  и помогают другим командам

  • Создаём пилоты продуктовых Agile-команд, куда постепенно начинаем высаживать мобильных разработчиков

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

  • За 3 месяца приводим в порядок платформу и делаем новую версию дизайн-системы

  • К этому моменту начинаем высаживать мобильных разработчиков в продуктовые команды и фактически запускаем их

  • Активно внедряем в командах agile-практики с параллельно идущими двухнедельными спринтами и с большим общим демо в конце

  • Запускаем release train (этим занималась отдельная релизная команда)

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

Все бы хорошо, но вернёмся к ошибке, которая была изначально.

Отдел Enterprise архитектуры изначально склонял все команды использовать только Backend Driven UI подход, независимо от того, подходит ли он к��нкретной команде или нет. Наша же команда все перевернула наоборот: все теперь надо писать на связке “натив” + REST, что ничем не лучше.

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

Как оказалось, сам разработанный протокол Backend Driven UI был довольно многофункциональными и поддерживал множественные взаимосвязи между различными компонентами UI: например, можно было навесить настройку логики отображения компонентов в зависимости от введенных полей или состояния различных слайдеров - особенно актуально при заполнении заявок или анкет, например, на кредит. Непосредственно перед отображением экрана движок просчитывал все эти взаимосвязи, Но изначально он не понимал сколько всего таких связанных компонентов и когда он закончит их обработку. Поэтому разработчики просто вставили фиксированный таймаут в несколько секунд для любого экрана, независимо от того, есть там связанные компоненты или нет. Стало понятно, что это просто алгоритмическая проблема и ее можно решить, что буквально за неделю ребятами и было сделано. Экраны начали загружаться практически мгновенно за вычетом периодических проблем на уровне бэкэнда и тестовых стэндов. 

Когда я вернулся к команде менеджмента с хорошими новостями о нашем движке и с предложением оставить весь разработанный на нативном генераторе форм функционал “как есть”, только переделать  UI компоненты под новые… меня попросили об этом не распространятся: уже все были “заряжены” полностью переделывать все мобильное приложение. Фактически предстояло переделать все фичи, все экраны, добавить много бизнес-логики, добавить REST запросы и соответственно провести много-много работы на стороне бэка, чтобы поддержать нужные API. 

Все были “заряжены”: отдел системной аналитики в спешном порядке и с большим энтузиазмом готовил новую системную аналитику, а отдел дизайна создавал новую дизайн-систему и составлял список и карту экранов, которые нужно перерисовать. 

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

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

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

Оборачиваясь назад

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

  • Не надо торопиться все переделывать, все критиковать и пытаться сделать “как в больших современных компаниях”, даже если это кажется очевидным. Специалисты, которые работали до тебя, скорее всего чем-то руководствовались, провели большую и сложную работу. Да, такая работа может стать неактуальной, или внешние факторы могут внести свои коррективы. Но в любом случае, это большая работа, нужно уметь почерпнуть опыт предшественников, понять, чем они руководствовались.

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

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

  • К сожалению или к счастью, большинство ИТ-шников при долгосрочном планировании берут на себя больше обязательств и фичей к реализации, чем следовало. Даже если вы думаете, что вы это делали 100 миллионов раз, подумайте еще раз - чаше лучше обещать меньше, но выполнить и быть героем, чем наообещать, сделать тот же самый объем, что в предыдущем варианте, и быть тем самым винторогим существом :)

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

Продолжение следует…