Привет, Хабр! В этой серии статей я хотел бы поделиться опытом создания большой команды мобильной разработки и самих мобильных приложений в одной крупной финансовой организации, об архитектуре, принимаемых решениях и их последствиях, о допущенных ошибках и сделанных выводах.
Что тут интересного, скажите вы? Любой 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 спасет положение дел при разработке конкретно этих мобильных приложений, хотя от него и пытались изначально по-максимуму отказаться. Но это тема следующих частей. А в следующей я постараюсь подробно рассказать про систему найма, построенные процессы в мобильных командах и немного про служебные сервисы на бэке, а также пачку ошибок про микроменеджмент.
Продолжение следует…