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

Про оригинал

Touchlab — одни из пионеров и евангелистов технологии Kotlin Multiplatform.
Они сделали SKIE и KMMBridge, множество статей и видео про опыт разработки на KMP.
Недавно они выпустили статью, тема которой схожа с тем, над чем я работал в прошлом году: подход к масштабированию KMP через разработку фич.
Поэтому захотелось перевести её на русский язык.

Предыстория

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

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

  • Вы создаете эти приложения с командой нативных мобильных специалистов (не только Android-разработчики, но и iOS и они работают вместе).

  • «Команда» — это как минимум 2-3 разработчика, которые разбираются в специфике своей платформы.

  • Ваша цель — организовать разработку на KMP с перспективой. Это не просто несколько модулей, а чтобы KMP покрывал значительный объем вашего кода в будущем.

Контекст важен

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

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

Основная же сложность в том, что текущие подходы к KMP ориентированы не очень хорошо применимы к нативным мобильным командам, а скорее ориентированы либо на Android либо на «мобильных фуллстеков».

Что такое «масштабирование»?

Основные цели при развитии Kotlin Multiplatform:

  • Использование KMP для значительной части вашего кода

  • Эффективная разработка c KMP

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

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

> KMP имеет ценность только в том случае, если вы получаете какую-то выгоду от его использования. Количество мультиплатформенного кода, которое вы пишете, и насколько эффективно вы его пишете, определяет эту ценность.

Большинство команд начинают пробовать KMP с какой-то библиотеки.
В такой модели — общий код находится в отдельном репозитории, имеет своё версионирование и подключается артифактом, как сторонняя библиотека.
Этот подход прост в настройке и не оказывает существенного влияния на повседневный рабочий процесс команд.
Touchlab рекомендует пробовать и примерять KMP именно с библиотечной модели разработки.

Touchlab так же рекомендует переходить с подключения KMP-библиотек в виде бинарных зависимостей на подключение в виде исходников.

Хотя на KMP легко реализовать библиотеку, вы не должны останавливаться только на библиотеках.
Нужно переходить к разработке фич.

Отличия библиотек и фич

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

Разработка библиотеки — это то, как это звучит. Вы пишете некоторый код библиотеки. Его основные характеристики:

  • Кусочки логики напрямую не связаны с вашей повседневной логикой приложения

  • Публикация с (примерно) последовательными версиями

  • Обычно размещается в отдельном репозитории

Не так важно, какая именно логика находится в вашей библиотеке.
Важно то, что код библиотеки живет в своём собственном цикле разработки, отдельно от цикла разработки приложения.
Примером может быть общий сетевой код, особенно общие контракты, или сложная бизнес-логика, например, какие-то расчеты.

Внешний цикл разработки и версионирование означают, что вы не пишете код библиотеки одновременно с кодом вашего приложения. Они слабо связаны.

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

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

Почему масштабирование — это сложно?

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

Логика, которую вы пишете для поддержки вашего UI, должна редактироваться как единое целое. Нажатие кнопки должно что-то «сделать». Хотя вы можете написать эту логику отдельно, это будет очень раздражающе и неэффективно.

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

Монорепо спешит на помощь?

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

Первопричина всё та же. Любое изменение общего кода влияет на оба приложения. А значит каждое изменение повлечет его обвязку и тестирование в обоих приложениях.
Это связывает логику двух приложений (что хорошо) и сами команды разработчиков (Android и iOS), чего было меньше в случае с двумя чисто нативными приложениями. Подробности, почему это может быть проблемой приведены в статье.

Подводя итог, можно сказать, что объединение кода в монорепо без сближения Android и iOS команд может привести к более медленному, сложному и потенциально неэффективному процессу разработки.

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

Объединение команд

Общаясь с разработчиками и менеджерами, интересующимися KMP, обнаружили, что желание «объединить команды» встречается довольно часто.
Вместо разработчиков Android и iOS все будут изучать обе платформы и работать как одна команда.

Это уже не первая попытка за те около 15 лет, которые существует мобильная разработка.
Для выравнивания ресурсов менеджерам хочется иметь универсальных мобильщиков, знающих обе платформы.
Каждые несколько лет аргументы о том, почему сейчас самое время, обновляются.
Современные аргументы фокусируются на сходстве Kotlin и Swift или Compose и SwiftUI.

Несмотря на это в большинстве команд остались именно одно-платформенные разработчики.

Что общего у более поздних аргументов со старыми призывами к слиянию команд, так это теоретические размышления без реальных результатов.
Нет никаких доказательств того, что это сработает. Это не значит, что это невозможно с KMP, просто это рискованно.

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

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

Масштабирование не обязательно должно быть сложным

Основные выводы таковы:

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

  • Подход работы с KMP как с библиотекой не работает при разработке фич

  • Объединение кода нативных приложений и KMP в один репозиторий создает новые сложности.

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

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

Учитывайте, а не ломайте их процессы.

Заключение

Сама статья кажется нагнетающей, но я постарался оставить основные тезисы, которые я увидел на собственном опыте в миграции на KMP продуктовой фичb компании с большим количеством разработчиков на одном приложении.
Самое главное, что тогда у нас получилось: мы проверили в бою, что KMP не разваливает приложение (в плане перфоманса, крашей), хотя такие опасения были в у коллег в самом начале, когда сравнивали технологию с предыдущими менее удачными кроссплатформами, такими как ReactNative, Xamarin.
Для этого мы провели много исследований, адаптаций зависимых библиотек, AB-тестов.
Сложнее оказалось как раз адаптироваться под те процессы, которые уже есть в командах.

Об этом опыте можно посмотреть два видео:
С технической точки зрения: Вызовы масштабируемости Kotlin Multiplatform на большом проекте
И с организационной: Как затащить новую технологию

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

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