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

Как реализовать многомодульную архитектуру?

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

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

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

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

Реализация многомодульной архитектуры в Android-приложении

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

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

  • Ускорение сборки за счет кэширования модулей и параллельной компиляции
  • Четкое разделение ответственности между командами
  • Улучшение тестируемости из-за изоляции компонентов
  • Контроль зависимостей и предотвращение циклических ссылок
  • Возможность динамической доставки через App Bundle

Ключевые типы модулей

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

  1. :app — сборочный модуль, содержащий точку входа
  2. :core — общие утилиты, расширения, базовые классы
  3. :data — репозитории, источники данных, модели
  4. :domain — бизнес-логика, use case, интерфейсы репозиториев
  5. :feature:* — модули конкретных фич с UI и ViewModel
  6. :navigation — навигация между фичами
  7. :ui-components — общие UI-компоненты

Практическая реализация

1. Настройка структуры проекта

Создаем модули через File → New → New Module в Android Studio. Каждый модуль имеет свой build.gradle.kts:

// build.gradle.kts для feature модуля
plugins {
    id("com.android.library")
    id("org.jetbrains.kotlin.android")
}

android {
    namespace = "com.example.feature.auth"
    compileSdk = 34
    
    defaultConfig {
        minSdk = 24
    }
    
    buildFeatures {
        compose = true
    }
}

dependencies {
    implementation(project(":core"))
    implementation(project(":domain"))
    
    // Общие зависимости для всех feature модулей
    implementation(libs.androidx.lifecycle.viewmodel)
    implementation(libs.koin.android)
}

2. Управление зависимостями через Version Catalog

В gradle/libs.versions.toml централизуем версии зависимостей:

[versions]
kotlin = "1.9.0"
compose = "1.5.0"

[libraries]
androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "core-ktx" }
koin-android = { module = "io.insert-koin:koin-android", version.ref = "koin" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }

3. Конфигурация зависимостей между модулями

// settings.gradle.kts
include(":app")
include(":core")
include(":data")
include(":domain")
include(":feature:auth")
include(":feature:profile")
include(":navigation")

4. Реализация чистой архитектуры

Domain модуль (чистая бизнес-логика):

// :domain/src/main/kotlin/com/example/domain/repository/UserRepository.kt
interface UserRepository {
    suspend fun getUser(id: String): User
    suspend fun updateUser(user: User)
}

// :domain/src/main/kotlin/com/example/domain/usecase/GetUserUseCase.kt
class GetUserUseCase(
    private val repository: UserRepository
) {
    suspend operator fun invoke(id: String): User {
        return repository.getUser(id)
    }
}

Data модуль (реализация репозиториев):

// :data/src/main/kotlin/com/example/data/repository/UserRepositoryImpl.kt
class UserRepositoryImpl(
    private val api: UserApi,
    private val dao: UserDao
) : UserRepository {
    override suspend fun getUser(id: String): User {
        // Логика получения данных
    }
}

Feature модуль (UI слой):

// :feature:profile/src/main/kotlin/com/example/feature/profile/ProfileViewModel.kt
class ProfileViewModel(
    private val getUserUseCase: GetUserUseCase
) : ViewModel() {
    private val _state = MutableStateFlow(ProfileState())
    val state: StateFlow<ProfileState> = _state.asStateFlow()
    
    fun loadProfile(userId: String) {
        viewModelScope.launch {
            _state.value = _state.value.copy(loading = true)
            val user = getUserUseCase(userId)
            _state.value = _state.value.copy(user = user, loading = false)
        }
    }
}

Критические аспекты реализации

Управление видимостью API

Используем интерфейсы и публичные API модулей для контроля доступа:

// Внутри feature модуля - internal видимость
internal class ProfileViewModel @Inject constructor(...)

// Публичный API модуля для навигации
class ProfileFeature {
    fun createDestination(userId: String): Route {
        return object : Route {
            override fun createScreen(): Screen = ProfileScreen(userId)
        }
    }
}

Избегание циклических зависимостей

  • Все зависимости должны быть однонаправленными
  • Используем Dependency Inversion Principle через интерфейсы
  • Общие зависимости выносим в :core модуль

Оптимизация сборки

// build.gradle.kts для настройки параллелизма
android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
    
    kotlinOptions {
        jvmTarget = "17"
        freeCompilerArgs += listOf(
            "-Xopt-in=kotlin.RequiresOptIn"
        )
    }
}

Инструменты и практики

  1. DI-фреймворки: Koin, Dagger Hilt или Kodein для управления зависимостями
  2. Навигация: собственный роутер или Jetpack Navigation с multi-module support
  3. Тестирование: модульные тесты для domain/data, интеграционные для feature
  4. CI/CD: кэширование артефактов сборки, инкрементальная компиляция

Распространенные ошибки

  • Слишком мелкие модули — создают избыточную сложность
  • Нарушение слоев архитектуры — feature модуль не должен зависеть от data
  • Отсутствие публичного API — приводит к связыванию модулей
  • Игнорирование инкрементальной сборки — теряется главное преимущество

Заключение

Реализация многомодульной архитектуры — это инвестиция в масштабируемость и поддерживаемость проекта. Начинать стоит с выделения :core и :domain модулей, затем постепенно дробить монолитный код на feature-модули. Ключевой успех — в соблюдении принципа единой ответственности для каждого модуля и построении однонаправленного графа зависимостей. Современные инструменты Gradle и Android Studio предоставляют все необходимое для эффективной работы с такой архитектурой.

Как реализовать многомодульную архитектуру? | PrepBro