Источник: Nuances of Programming
Создание модульных приложений/библиотек для Android дает целый ряд преимуществ, а процессу разработки следует уделять достаточно внимания. Перечень получаемых плюсов достаточно большой, перечислим лишь основные из них.
Изоляция
Изоляция модулей сократит побочные эффекты и непредсказуемые задержки в исполнении кода. С увеличением количества строк они становятся намного опаснее, а в небольших и изолированных частях/модулях риск возникновения проблем гораздо меньше.
Возможность повторного использования
Одни и те же модули можно применять в разных приложениях. Если вы хотите использовать подход с монорепозиторием для нескольких приложений, тогда каждая часть кода будет модулем. Также вы можете отправить их все в репозиторий maven, что упростит использование из других проектов. Функция загрузки изображений применяется достаточно широко.
Зависимости
Модули включают внутренние зависимости, не подверженные влиянию других модулей. Это заставляет проектировать поведение независимым от реализации. Например, широко используемая функция загрузки изображения по ссылке на сайте.
Вот самое простое расширение для загрузки изображений с помощью библиотеки Picasso. Его размещение в отдельном модуле лишь раскроет функцию load . Поэтому нам не потребуется добавлять зависимость Picasso в функциональные модули.
Picasso можно с легкостью изменить с помощью Glide или любой другой библиотеки загрузки изображений. Дело в том, что Picasso представляет собой внутреннюю зависимость и ее можно изменять в любое время, не влияя на открытое поведение.
Модуляризация позволяет разделять внутренние и внешние зависимости.
Основной упор на поведение
Разделение на модули заставляет строить модели поведения. Как и в примере с загрузкой изображений, мы раскрываем только функцию load() , не имеющую ничего общего с Picasso.
Скорость сборки
Если в модуле нет изменений, то он не будет повторно собираться. Это коснется только измененных и зависящих от него частей.
Методы модуляризации
Есть несколько подходов к модуляризации. Их выбирают в зависимости от проекта, команды и организации.
Функциональная модуляризация
Особенности:
· Подходит для больших проектов/команд.
· Предоставляет расширенное применение модулей.
· Функциональные свойства можно легко использовать в нескольких приложениях.
· Обеспечивает слабую связь между функциональными модулями.
· Ограничена более строгими правилами.
При подобном подходе у вас будет слишком много модулей. Модуль app во втором варианте делится на функциональные модули. Некоторые общие коды функций также вынесены в отдельные части.
Модуляризация по слоям
Все функциональные модули объединены в модуле app . Это менее строгий подход. Но вы все равно можете использовать разделенные функциональные модули.
· Меньше модулей и меньше изоляции, но управление проще.
· Только слои могут использоваться в нескольких приложениях.
· Все свойства находятся в модуле app , который все же сохраняет свою монолитность.
· Модуль common содержит расширения DTO, которые могут использоваться всеми остальными модулями.
· Модуль network содержит классы, относящиеся к Retrofit, интерфейс API и перехватчики.
· Модуль data содержит различные данные, включая локальные и удаленные репозитории.
· Модули library не зависят от функций или других модулей, таких как загрузка изображений или библиотека аналитики.
· Модуль app содержит все функции и классы, связанные с пользовательским интерфейсом, такие как Activity, Fragment, ViewModels и т. д.
Использование common-module.gradle
Примените этот скрипт gradle ко всем функциональным модулям — так вам не придется дублировать ее для каждого из них.
Ресурсы
Ресурсы конкретных функций могут находиться в функциональных модулях, однако их разделение затруднит организацию. Поэтому лучше хранить их в модуле common .
Если для организации строк между клиентами Android/iOS используется многоязычный инструмент, то обычно он дает один файл strings для каждого языка. Возможно, стоит объединить строки.
Если применяются динамические модули, вам нужно позаботиться о ресурсах, которые могут повлиять на размер приложения/модуля, например, drawables.
DTO и часто используемые расширения могут находиться в модуле common , потому что их может применять каждый функциональный модуль.
Отчет охвата Jacoco
Каждый модуль имеет собственный вывод отчетов. Поэтому вам потребуется просмотреть все отчеты охвата в одном месте. Сделать это можно с помощью этого скрипта .
Добавьте строку apply from: “$rootDir/jacoco.gradle” в файл build.gradle каждого модуля.
Вот пример build.gradle:
Инструментальное тестирование
Упростить задачу тестирования классов Activity/Fragment можно с помощью mock-объекта для некоторого поведения.
В данном случае достаточно только внедрения mock-репозитория.
Читайте также:
Перевод статьи Faruk Toptaş : Android App Modularization Tips