Скорость команды часто пытаются измерить количеством сильных разработчиков. Но самый быстрый человек в хаотичной системе обычно не ускоряет команду. Он просто первым начинает компенсировать её проблемы.
В большом проекте скорость чаще теряется не в коде, а между мыслью «надо поменять вот это» и моментом, когда изменение можно будет увидеть, обсудить, проверить и выпустить.
Представьте: большое iOS приложение для широкой аудитории, несколько рынков, которые собираются из одного проекта, часто обновляющиеся данные и экраны, которые product хочет менять быстрее, чем новый релиз успевает дойти до пользователей.
В такой среде архитектура нужна не для красивой схемы. Она нужна, чтобы изменения были дешёвыми.
Запускать модули отдельно
Одна из самых дорогих операций в большом проекте — дождаться полной сборки.
Разработчик может прийти поправить один экран, изменить несколько строк и затем ждать, пока соберётся весь продукт: соседние модули, ресурсы, зависимости и части, которые не имеют отношения к задаче.
А если сделать так, чтобы крупные разделы можно было запускать отдельно — только с нужной функциональностью?
Это даёт простой эффект: изменение быстрее видно, его не страшно переделать. Можно изолированно проверить несколько связанных экранов, а новому разработчику не нужно сначала разобраться во всём проекте, чтобы принести пользу в одном разделе.
Если результат долго ждать, люди начинают гадать, но если его можно увидеть быстро — проверяют гипотезы.
Экраны отдельно, но не приложения
Но отдельный запуск разделов не значит, что каждый экран становится отдельным приложением.
Другая частая ловушка мобильной разработки — разложить один экран на множество формальных ролей и файлов. В итоге логика оказывается размазана так, что для изменения одной кнопки нужно пройти весь ритуал: понять, где живёт событие, кто передаёт его дальше и в каком из слоёв лежит нужное состояние.
Для многих экранов достаточно пяти вещей:
View — то, что видит пользователь.
Model — состояние экрана: загрузка, данные, ошибка, выбранный элемент.
Input — с чем экран открывается.
Output — что он возвращает, когда закончил работу.
Builder — место, где собираются зависимости.
Всё.
Экран не знает про соседей. Пока его нет на экране, он ничего не делает — не качает данные и не живёт своей жизнью в фоне.
Навигация устроена чуть сложнее, потому что она независима от конкретного механизма SDK. Цепочку экранов можно вложить в другую цепочку и открыть заново в другом месте продукта, не таща за собой весь маршрут. Для команды это значит одну простую вещь: экран можно переставить, не разбирая приложение. Для продукта — новый сценарий быстрее собирается из готовых кусков.
Проверять на реальном устройстве
Один CTO как‑то заметил странное: один iOS‑разработчик ходит с Android. Ну или наоборот: один iOS‑разработчик заметил, что один CTO ходит с iPhone. Последнее как раз не странно. Кроме шуток, это одна простая мысль: разработчик платформы должен регулярно пользоваться реальным устройством и иметь возможность отлаживать приложение там, где им будут пользоваться люди.
Представьте, что данных у вас много, они обновляются часто, недостаточно смотреть на время выполнения в симуляторе.
Важно проверить, как приложение ведёт себя на устройстве: не теряет ли интерфейс отзывчивость, не расходует ли лишнюю батарею, не нагревается ли устройство после нескольких минут работы.
В одном R&D‑сценарии мы сравнивали несколько способов обработки данных. Один вариант занимал почти две секунды. Другой был быстрее, но заметно нагревал устройство при регулярных обновлениях. Данные постоянно проходили длинный путь: JSON, затем DTO, затем доменные модели, затем view‑модели, затем обновление интерфейса. И этот цикл повторялся снова при каждом обновлении.
Процессор на устройстве не остывал в принципе, а на симуляторе этого было не заметно.
Сократили количество моделей — не более двух на всем пути от запроса до UI (снова уменьшили количество сущностей). Убрали лишние преобразования. Перестали многократно проходить структуру JSON в поисках нужных полей (что делает почти любой парсер по‑умолчанию).
Жара ушла, устройство перестало стабильно нагреваться. Но процессор перестал получать ту же тяжёлую работу заново при каждом новом сообщении.
Что это даёт команде
Скорость и гибкость большого мобильного приложения — это не героизм и не характер отдельных людей.
Это следствие того, как устроена система:
Сколько лишних действий разработчику нужно совершить, чтобы увидеть своё изменение.
Можно ли быстро и изолированно проверить изменение.
Может ли экран менять своё место в пользовательском сценарии без переделки всего маршрута.
Умеет ли приложение работать с часто меняющимися данными без перегрева устройства и деградации интерфейса.
Можно ли менять контент и конфигурацию без срочного релиза.
Когда это настроено, команде проще раньше показывать незавершённые решения, замечать риски и спорить по существу.
Но технической системы недостаточно. Регулярные релизы без здоровой среды быстро превращаются в тревогу и выгорание.
О том, как устроить такую среду — тот самый vibe coding, но не тот, о котором сейчас все говорят, — напишу в следующей статье.
