← Назад к вопросам

Расскажите о многомодульной архитектуре в Android. Какие преимущества и как организовать?

3.0 Senior🔥 181 комментариев
#Архитектура и паттерны#Многомодульность

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

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Многомодульная архитектура в Android: концепция, преимущества и организация

В современной разработке Android приложений многомодульная архитектура (Multi-module architecture) стала стандартом для проектов среднего и крупного масштаба. Это подход, где приложение делится на логически независимые компоненты — модули (модули Gradle), каждый из которых отвечает за конкретную функциональность или уровень абстракции.

Преимущества многомодульной архитектуры

Основные преимущества перехода от монолитного к многомодульному проекту:

  • Ускорение сборки (Build Speed): Gradle может параллельно компилировать независимые модули и использовать механизм инкрементальной компиляции. Если изменения касаются только одного модуля (например, feature-auth), перекомпилируется только он, а остальные модули будут взяты из кэша. Это критично для больших проектов.
  • Чёткое разделение ответственности (Clear Separation of Concerns): Каждый модуль имеет строго определённую область ответственности. Это делает код более поддерживаемым (maintainable) и упрощает понимание структуры проекта для новых разработчиков.
  • Улучшение тестирования (Improved Testing): Модули, особенно содержащие чистую бизнес-логику (например, domain или core), можно тестировать независимо от Android Framework, что делает тесты быстрыми и надежными.
  • Контроль зависимостей и избегание циклических ссылок: Модули декларативно описывают свои публичные интерфейсы (через api vs implementation в Gradle). Это предотвращает случайное использование внутренних классов других модулей и возникновение циклических зависимостей, которые сложно разрешить.
  • Повторное использование кода (Reusability): Общие компоненты, такие как модуль core-network или core-ui, можно легко использовать в нескольких feature-модулях или даже в других проектах.
  • Более гибкая настройка CI/CD: Можно настроить pipelines для сборки и тестирования только изменённых модулей.
  • Подготовка к динамической доставке (Dynamic Delivery): Структура с независимыми feature-модулями является фундаментом для технологий like Play Feature Delivery, позволяющих загружать части приложения по требованию.

Как организовать многомодульный проект: типичная структура

Организация зависит от масштаба, но распространённый паттерн — разделение по слоям (layers) и функциональности (features).

// Структура проекта в build.gradle.kts (Project level)
include(
    ":app",              // Главный модуль-сборщик
    ":core:network",    // Модули общего назначения
    ":core:utils",
    ":core:ui",
    ":data",            // Модуль слоя данных (репозитории, источники)
    ":domain",          // Модуль бизнес-логики (модели, интерфейсы репозиториев)
    ":feature:auth",    // Независимые feature-модули
    ":feature:profile",
    ":feature:feed"
)

1. Модуль app

Это корневой Android Application модуль. Он собирает все остальные модули и содержит:

  • точки входа (Application, MainActivity)
  • высокоуровневую настройку (DI-граф, настройка аналитики)
  • минимальную логику, выступая преимущественно как интегратор.

2. Модули слоя core (или common)

Группа модулей, предоставляющих инфраструктурные возможности для всего проекта.

  • core-network: Конфигурация клиента (Retrofit/OkHttp), интерцепторы, DTO для API.
  • core-ui: Общие компоненты UI (кастомные View, базовые Fragment/Activity), темы, ресурсы.
  • core-utils: Extension functions, вспомогательные классы, не относящиеся к конкретной feature.
// Пример декларации зависимости в feature-модуле
// В build.gradle.kts модуля :feature:auth
dependencies {
    // Используем 'api', если хотим экспортировать эту зависимость
    api(project(":domain"))
    // Используем 'implementation', для внутреннего использования
    implementation(project(":core:network"))
    implementation(project(":core:ui"))
}

3. Модуль domain

Слой чистой бизнес-логики (business logic). Часто это чистый Kotlin модуль (без зависимости на com.android.application или com.android.library).

  • Entity-классы (например, User, Post)
  • Интерфейсы репозиториев (UserRepository)
  • Use Cases / Interactors — классы, инкапсулирующие конкретные бизнес-операции.
// Пример Use Case в модуле :domain
class GetUserUseCase(private val userRepository: UserRepository) {
    suspend operator fun invoke(userId: String): User {
        return userRepository.getUser(userId)
    }
}

4. Модуль data

Реализует контракты (интерфейсы репозиториев), объявленные в domain. Здесь живут:

  • конкретные RepositoryImpl
  • источники данных (RemoteDataSource, LocalDataSource)
  • мапперы для преобразования DTO/DAO в Domain Entity.

5. Feature-модули (например, :feature:auth)

Независимые модули, представляющие завершенные пользовательские сценарии. Они зависят от domain, data и core, но не зависят друг от друга. Это ключ к независимости и повторному использованию. Внутри они могут использовать свою собственную внутреннюю архитектуру (например, MVVM).

  • Presentation слои (ViewModel, Fragments/Compose)
  • специфичные для фичи Use Cases (если не общие)
  • собственные DI-компоненты.

Критические практики при организации

  • Контроль зависимостей: Используйте api для передачи зависимости транзитивно и implementation для внутреннего использования. Это уменьшает время перекомпиляции и предотвращает "протекание" внутренних API.
  • Чистые модули (Pure Kotlin modules): Максимально используйте модули без Android-зависимости (org.jetbrains.kotlin.jvm) для логики. Их компиляция быстрее, и они не требуют Android SDK.
  • Публичные контракты: Определите, что каждый модуль экспортирует (через публичные классы/интерфейсы) и что остается его внутренней реализацией. Используйте пакеты internal или видимость private.
  • Настройка навигации: Для navigation между feature-модулями используйте либо динамические ссылки (Deep Links), либо выделенный модуль navigation, содержащий маршруты и координацию.

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