Может ли Kotlin Multiplatform сократить трудозатраты при разработке одного продукта под несколько платформ? Мои вычисления говорят, что да, на 21%. Покажу это на примере своего хобби-проекта GitBudget для Android + iOS.

Текущее положение дел

Одним из популярных способов разработки под несколько платформ является схема «одна платформа - одна команда разработки». Например, взглянем на известный мессенджер, заточенный под парковки. Некоторое время назад я словил следующую багу исчезновения сообщений:

Как следует из видео, в ходе переписки с GigaChat у меня пропадали сообщения: на Android бага проявилась лишь раз (4-я секунда видеозаписи), на Web бага повторялась стабильно. Разное поведение на разных платформах свидетельствует о том, что продукт под разные платформы делают разные команды разработки. У каждой команды свой язык программирования, своя архитектура, свой процесс code review, свой ун��кальный набор порождаемых багов, своя команда тестирования, свой ФОТ и т.д..

Таким образом, чем больше мы дублируем в коде, тем больше мы вынуждены дублировать организационно. КМП может помочь сократить дублирование части кода, но, конечно, не полностью, а лишь на определённый процент. Каков этот процент? Посчитаем на примере моего хобби-проекта GitBudget.

Обзор GitBudget

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

  1. Перерасход: Насколько на текущий день траты превышают план (бюджет)

  2. Осталось ₽/д: Сколько можно потратить сегодня и в последующие дни текущей недели средств, чтобы не превысить недельный план (бюджет)

Углубляться в формулу и в архитектуру сейчас не буду, т.к. они не предмет данной статьи. Пытливый читатель всё это найдёт сам на GitHub.

Ознакомимся с внешним видом приложения на Android и iOS:

Android, iOS
Android, iOS

Никакой фантастики в UI/UX нет, все элементы интерфейса стандартные (и даже не везде выровненные). Использование приложения на текущий момент сводится к трём действиям пользователя:

  1. Вставить из буфера обмена траты за вчера (Spent)

  2. Вставить из буфера обмена остаток баланса на вчерашний день (Morning balance)

  3. Скопировать итоговый расчёт в буфер обмена (Result)

Трудозатраты на разработку

Для удобства подсчёта условимся о разделении всего кода приложения на три группы:

Группа

Пример

Файлы Android

Файлы iOS

1

UI

Jetpack Compose, SwiftUI

MainActivity.kt, VM.kt

AppView.swift, VM.swift

2

Платформа

ClipboardManager, UIPasteboard

budget.kt, main.kt, other-android.kt, registerOneliners.kt

budget.swift, cld-ios.swift, other-ios.swift

3

Логика

budgetShouldResetMorningBalance

budgetFun.kt, entities.yml

budgetFun.kt, entities.yml

КМП в GitBudget я использую лишь для логики, а UI и платформенный код нативные. Почему так? Потому что логика полностью под моим контролем, она обновляется по моему усмотрению. С UI и платформенным кодом ситуация иная - это собственность корпораций Apple и Google, они задают правила игры и обновляют UI с платформой по своему усмотрению (например, придумывают Liquid Glass, от которого не увернуться).

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

Первый показатель: Количество строк кода

Платформа

Всего

UI

Платформа

Логика

1

Android

692

160 (23%)

221 (32%)

311 (45%)

2

iOS

540

90 (16%)

139 (26%)

311 (58%)

Вывод-1: 311 строк логики для iOS я не писал повторно благодаря КМП, это 58% всего кода iOS.

Вывод-2: 311 ненаписанных повторно строк кода для iOS с точки зрения обеих платформ (692 + 540 = 1232) означают, что 25% кода всего проекта я не писал повторно.

Второй показатель: Время реализации функциональности

Под запись я добавил кнопку Paste для поля ввода Morning balance как для Android:

Так и для iOS:

В итоге получились такие цифры:

Платформа

Тип реализация

Особенности реализации

Время

1

Android

Первичная

Создаём новую функциональность, которой не было, собираем почти все грабли

17:34

2

iOS

Вторичная

Подключаем готовую логику, дописываем лишь UI, граблей практически нет

07:33 (43%)

Вывод-3: Повторение функциональности на iOS с готовой логикой заняло на 57% меньше времени, т.е. произошло в 2 раза быстрее

Вывод-4: Если принять, что без КМП функциональность на каждой из двух платформ делали бы в сумме 17:34 * 2 = 35:08 минут, то сэкономленные 10 минут при повторении функциональности для iOS означают, что для всего проекта я сэкономил 21% времени.

Выводы

Итак, экономия с КМП в цифрах выглядит так:

  1. Количество строк для iOS снизилось на 58%

  2. Суммарно количество строк кода по всему проекту снизилось на 25%

  3. Время, необходимое на повторение функциональности для iOS, снизилось на 57%

  4. Суммарно затраченное время по всему проекту на реализацию функциональности снизилось на 21% (эту цифру я использовал в самом начале статьи)

Вопросы читателю

  1. Суммарная экономия в 21% по времени проекта - это много или мало?

  2. Окупает ли экономия в 21% явно не однодневный переход команд на новый процесс разработки?

  3. Насколько важен синхронный выпуск функциональности на обе платформы, причём работающей одинаково на каждой платформе?