Почему мобильное приложение должно быть разделено на отдельные модули?
Что проверяют
Отличаете ли вы реальные выгоды от лозунгов и понимаете ли, чем модуляризация оплачивается. Следом спрашивают, как одна фича открывает экран другой, ничего про неё не зная.
Как отвечать
Опирайтесь на механизмы Gradle и на изоляцию кода, а не на слова про поддерживаемость.
- скорость сборки: пересобираются только изменённые модули и зависимые от них, независимые собираются параллельно и берутся из build cache.
implementationвместоapiобрезает граф пересборки: правка внутри модуля не тянет перекомпиляцию транзитивных потребителей; - изоляция:
internalи отсутствие зависимости физически запрещают залезть в чужую фичу, внутри одного модуля это держится на договорённости и ревью; - параллельная работа: у модуля есть владелец, конфликты в общих файлах реже, права на ревью раздаются по каталогам;
- тесты: прогон тестов одного модуля вместо всего приложения, на пул-реквесте можно гонять только затронутые;
- доставка: выкинуть код из первичной установки умеют только dynamic feature modules с Play Feature Delivery, обычные модули целиком лежат в одном артефакте.
Расскажите типовую нарезку: :app как сборщик, :core:* (сеть, база, дизайн-система), :feature:* по продуктовым областям. В строгом варианте фича делится на :api и :impl, соседи видят только :api. Взаимные вызовы идут через интерфейсы api-модуля и внедрение зависимостей, переходы между фичами через абстракции маршрутов.
Цена: растёт время конфигурации Gradle, копится дублирование настроек (лечится каталогом версий и convention-плагинами в build-logic), появляются циклические зависимости и спор, куда положить общий класс. Тридцать модулей на маленькое приложение собираются медленнее одного.
Где спотыкаются
Утверждают, что модули уменьшают размер приложения. Обычные модули целиком попадают в один AAB, размер режут R8 и ресурсы, а не структура проекта.
Обещают ускорение сборки и вешают всё на один :core, через который проходит каждая зависимость. Правка в нём пересобирает проект целиком, выигрыш испаряется.
Не могут объяснить разницу между api и implementation, хотя именно она определяет, что и когда пересобирается.