0Pricing
Android Academy · Pelajaran

Mengelola Dependensi Modul

Jaga graf tetap bersih dan tanpa siklus.

Mengelola Dependensi Modul adalah pelajaran Android Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Android Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Android Academy mencakup 4 pelajaran total.

Graf Dependensi

Setiap modul menyatakan modul lain yang menjadi dependensinya. Semua ini membentuk graf dependensi. Graf yang sehat adalah DAG (graf berarah tanpa siklus): dependensi mengarah ke satu arah dan tidak pernah membentuk putaran.

Dalam pelajaran ini, Anda akan mempelajari cara menyatakan dependensi dengan rapi, memilih konfigurasi Gradle yang tepat, membagikan versi, dan mencegah siklus.

Menyatakan Dependensi Modul

Anda menambahkan dependensi pada modul lain dengan project(":path:to:module") di dalam blok dependencies. Jalurnya mencerminkan folder dan sesuai dengan yang Anda nyatakan di settings.gradle.kts.

// feature/profile/build.gradle.kts
dependencies {
    implementation(project(":core:data"))
    implementation(project(":core:designsystem"))
    implementation(project(":core:model"))
}

implementation vs api

Konfigurasi yang Anda pilih menentukan apa yang terekspos kepada konsumen:

  • implementation: dependensi bersifat privat. Modul yang bergantung pada modul Anda tidak dapat melihatnya. Ini adalah pilihan bawaan.
  • api: dependensi diekspos kembali (transitif). Gunakan ini hanya jika tipe publik Anda berasal dari dependensi tersebut.

Hampir selalu, utamakan implementation—ini meningkatkan kecepatan pembangunan karena perubahan pada dependensi tersembunyi tidak memaksa konsumen untuk dikompilasi ulang.

// core/data/build.gradle.kts
dependencies {
    // Repository signatures return :core:model types,
    // so consumers need to SEE it -> api
    api(project(":core:model"))

    // Network is an internal detail -> implementation
    implementation(project(":core:network"))
}

Mengapa implementation Mempercepat Pembangunan

Dengan implementation, Gradle mengetahui bahwa perubahan pada dependensi tersembunyi tidak dapat memengaruhi ABI publik modul. Jadi, konsumen tidak perlu dikompilasi ulang. Dengan api, perubahan merambat ke setiap konsumen transitif.

Aturan praktis: masukkan dependensi ke api hanya jika dependensi tersebut muncul dalam tipe publik modul (tipe pengembalian, parameter publik). Jika tidak, gunakan implementation.

// Public -> needs api
fun observeUser(): Flow<User>   // Flow and User leak out

// Internal -> implementation is enough
private val client: OkHttpClient // never exposed

Memusatkan Versi: Katalog Versi

Dengan banyak modul, Anda tentu tidak ingin mengulangi versi pustaka di mana-mana. Katalog versi Gradle (gradle/libs.versions.toml) mendefinisikan versi dan alias satu kali. Setiap modul merujuk pada alias yang sama.

# gradle/libs.versions.toml
[versions]
compose-bom = "2024.09.00"
retrofit = "2.11.0"

[libraries]
compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose-bom" }
retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }

Menggunakan Katalog dalam Modul

Modul kemudian merujuk pustaka melalui pengakses libs yang dibuat secara otomatis. Tanpa nomor versi dalam berkas pembangunan, pemutakhiran dapat dilakukan di satu tempat.

// core/network/build.gradle.kts
dependencies {
    implementation(platform(libs.compose.bom))
    implementation(libs.retrofit)
}

Dosa Terbesar: Siklus

Siklus terjadi ketika modul A bergantung pada B dan B kembali bergantung pada A (secara langsung atau melalui rangkaian). Gradle menolak membangun dependensi melingkar. Hal ini juga menandakan masalah desain: batas antara kedua modul tersebut tidak tepat.

// :feature:cart  -> implementation(project(":feature:checkout"))
// :feature:checkout -> implementation(project(":feature:cart"))
//
// Gradle error:
// Circular dependency between the following tasks:
// :feature:cart:compile -> :feature:checkout:compile -> :feature:cart:compile

Memutus Siklus

Untuk memutus siklus, ekstrak bagian yang digunakan bersama ke dalam modul yang lebih rendah yang dapat menjadi dependensi keduanya. Jika dua fitur membutuhkan data satu sama lain, kontrak bersama tersebut seharusnya berada di inti, bukan di salah satu fitur.

Dengan demikian, alur ke bawah kembali terbentuk: kedua fitur mengarah ke inti, dan inti tidak pernah mengarah kembali ke atas.

// Before: cart <-> checkout (cycle)
// After:  cart -> :core:order  <-  checkout

// core/order/OrderContract.kt
data class Order(val items: List<CartItem>, val total: Double)

// feature/cart    -> implementation(project(":core:order"))
// feature/checkout-> implementation(project(":core:order"))

Inversi: Bergantung pada Abstraksi

Terkadang modul tingkat rendah membutuhkan perilaku yang berada di tingkat lebih tinggi. Alih-alih bergantung ke atas, tentukan sebuah antarmuka di modul tingkat rendah dan biarkan modul tingkat tinggi menyediakan implementasinya melalui injeksi dependensi. Inilah inversi dependensi.

// core/analytics defines the contract
interface AnalyticsLogger {
    fun log(event: String)
}

// :app provides the real implementation and injects it down
@Module
@InstallIn(SingletonComponent::class)
object AnalyticsModule {
    @Provides
    fun logger(impl: FirebaseAnalyticsLogger): AnalyticsLogger = impl
}

Memvisualisasikan dan Menjaga Graf

Anda dapat meminta Gradle untuk mencetak atau merender graf modul, bahkan menambahkan pengujian yang menggagalkan pembangunan jika dependensi terlarang muncul (misalnya, modul inti bergantung pada fitur). Alat seperti plugin module-graph dapat membuat diagram secara otomatis.

# Print the project structure
./gradlew projects

# Inspect why :feature:home pulls in a library
./gradlew :feature:home:dependencies --configuration debugRuntimeClasspath

Contoh yang Bersih dan Tanpa Siklus

Berikut graf yang sehat. Bacalah dari atas ke bawah; tidak ada panah yang mengarah kembali ke atas, dan tidak ada dua modul yang saling menunjuk. Inilah tepatnya yang ingin Anda capai.

// :app
//   -> :feature:home   -> :core:data -> :core:network -> :core:model
//   -> :feature:profile -> :core:data -> :core:database -> :core:model
//   -> :core:designsystem
//
// Every path ends at :core:model. No cycles. Builds in parallel.

Pemeriksaan Singkat

Modul :core:network Anda hanya menggunakan OkHttpClient secara internal—kode tersebut tidak pernah muncul dalam tanda tangan fungsi publik. Konfigurasi Gradle mana yang seharusnya Anda gunakan untuk menyatakan dependensi OkHttp?

Rangkuman: Mengelola Dependensi Modul

Anda telah mempelajari cara menjaga graf modul tetap sehat:

  • Nyatakan dependensi modul dengan project(":path").
  • Gunakan implementation sebagai bawaan; gunakan api hanya untuk tipe yang ada di permukaan publik Anda.
  • Sentralisasikan versi dalam katalog versi (libs.versions.toml).
  • Jangan pernah membuat siklus—Gradle akan menolaknya; putuskan siklus dengan mengekstrak kode bersama ke bawah atau melakukan inversi menggunakan antarmuka.

Selanjutnya, Anda akan menghubungkan fitur satu sama lain melalui navigasi tanpa membuatnya saling terikat.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Mengelola Dependensi Modul” gratis?

Ya — teks lengkap “Mengelola Dependensi Modul” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Android Academy, upgrade ke CoddyKit PRO. Kursus Android Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Mengelola Dependensi Modul”?

Jaga graf tetap bersih dan tanpa siklus. Kamu berlatih Android Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Android Academy?

Tidak diperlukan pengalaman sebelumnya. Android Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.

Berapa lama pelajaran “Mengelola Dependensi Modul” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Android Academy ini?

Ya. Setiap pelajaran Android Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Mengapa Membuat Modul
  2. Modul Fitur dan Inti
  3. Mengelola Dependensi Modul
  4. Navigasi Antar-Modul
← Kembali ke Android Academy