0Pricing
Android Academy · Pelajaran

Modul Fitur dan Inti

Tetapkan batas modul.

Modul Fitur dan Inti adalah pelajaran Android Academy gratis di CoddyKit. Ini adalah pelajaran 2 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.

Dua Jenis Modul

Sebagian besar aplikasi Android yang dimodularisasi mengatur kode ke dalam dua jenis modul utama: modul feature dan core, ditambah modul :app yang tipis di bagian atas.

  • Modul feature berisi bagian aplikasi yang berhadapan dengan pengguna (sebuah layar atau alur).
  • Modul core berisi infrastruktur bersama yang digunakan banyak fitur.

Dalam pelajaran ini, Anda akan mempelajari cara membuat batasan tersebut dengan baik.

Anatomi Modul Feature

Modul feature seperti :feature:profile berisi semua hal yang dibutuhkan satu fitur: layar Compose, ViewModel, dan status antarmukanya. Modul ini bersifat vertikal: modul ini memiliki seluruh bagian, mulai dari antarmuka pengguna hingga view-model-nya.

Modul ini bergantung pada modul core untuk bagian-bagian bersama, tetapi seharusnya tidak bergantung pada modul feature lain.

// feature/profile/ProfileScreen.kt
@Composable
fun ProfileScreen(viewModel: ProfileViewModel = hiltViewModel()) {
    val state by viewModel.uiState.collectAsStateWithLifecycle()
    when (state) {
        is ProfileUiState.Loading -> CircularProgressIndicator()
        is ProfileUiState.Success -> ProfileContent((state as ProfileUiState.Success).user)
        is ProfileUiState.Error -> ErrorMessage()
    }
}

ViewModel Feature

Setiap fitur memiliki ViewModel-nya sendiri. ViewModel mengambil data melalui repositori dari modul core dan menyediakan status antarmuka pengguna. Modul feature tidak mengetahui cara data diambil, melainkan hanya kontrak repositorinya.

// feature/profile/ProfileViewModel.kt
@HiltViewModel
class ProfileViewModel @Inject constructor(
    private val userRepository: UserRepository // from :core:data
) : ViewModel() {
    val uiState: StateFlow<ProfileUiState> =
        userRepository.observeUser()
            .map { ProfileUiState.Success(it) }
            .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), ProfileUiState.Loading)
}

Anatomi Modul Core

Modul core bersifat horizontal: modul ini menyediakan satu kemampuan yang digunakan di berbagai fitur. Modul core yang umum meliputi:

  • :core:model — kelas data biasa yang digunakan bersama di mana saja
  • :core:network — klien Retrofit/Ktor
  • :core:database — penyiapan Room
  • :core:data — repositori yang menggabungkan jaringan + basis data
  • :core:designsystem — tema dan composable yang dapat digunakan kembali
// core/model/User.kt
data class User(
    val id: String,
    val name: String,
    val avatarUrl: String
)

Modul Sistem Desain

:core:designsystem adalah salah satu modul yang paling sering digunakan kembali. Modul ini menyimpan MaterialTheme, skema warna, tipografi, dan composable yang dapat digunakan kembali seperti tombol dan kartu. Setiap fitur menerapkan tampilan yang sama tanpa menyalin kode.

// core/designsystem/AppTheme.kt
@Composable
fun AppTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
    val colors = if (darkTheme) DarkColors else LightColors
    MaterialTheme(
        colorScheme = colors,
        typography = AppTypography,
        content = content
    )
}

Modul Data Memiliki Repositori

Modul :core:data menyediakan antarmuka repositori yang menjadi dependensi fitur, sekaligus menyembunyikan implementasinya. Modul ini biasanya bergantung pada :core:network dan :core:database, lalu menggabungkannya menjadi satu-satunya sumber kebenaran.

// core/data/UserRepository.kt
interface UserRepository {
    fun observeUser(): Flow<User>
    suspend fun refresh()
}

// core/data/OfflineFirstUserRepository.kt
internal class OfflineFirstUserRepository @Inject constructor(
    private val api: UserApi,        // :core:network
    private val dao: UserDao         // :core:database
) : UserRepository {
    override fun observeUser(): Flow<User> = dao.observe().map { it.toUser() }
    override suspend fun refresh() { dao.upsert(api.fetch().toEntity()) }
}

Pertahankan model dan sistem desain tetap ringan

Modul inti dengan tingkat paling rendah seharusnya hanya bergantung pada sesedikit mungkin hal. Idealnya, :core:model sama sekali tidak memiliki dependensi Android—hanya kelas data Kotlin biasa. Dengan begitu, modul ini dapat digunakan di mana saja dan dibangun dengan cepat.

Jika :core:model mulai bergantung pada Retrofit atau Room, setiap modul yang menggunakan kelas data Anda akan ikut membawa pustaka-pustaka berat tersebut.

// core/model/build.gradle.kts
plugins {
    id("myapp.jvm.library") // pure Kotlin, no Android
}
// No Retrofit, no Room, no Compose here — just data classes

Modul :app yang Tipis

Modul :app adalah perakit. Modul ini seharusnya hanya berisi sedikit logika: kelas Application, satu-satunya MainActivity, NavHost tingkat atas, dan pengaturan injeksi dependensi. Semua layar yang sebenarnya berada di modul fitur.

Modul aplikasi yang tipis berarti sebagian besar perubahan terjadi di fitur, sehingga modul aplikasi jarang perlu dibangun ulang.

// app/MainActivity.kt
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            AppTheme {            // from :core:designsystem
                AppNavHost()      // routes into :feature:* screens
            }
        }
    }
}

Membuat Batasan yang Baik

Bagaimana Anda menentukan sesuatu menjadi modul? Berikut beberapa panduan praktis:

  • Fitur = layar atau alur yang dapat disebutkan oleh pengguna (Beranda, Profil, Pembayaran).
  • Modul inti = kemampuan yang digunakan kembali oleh 2 fitur atau lebih.
  • Jika dua fitur sama-sama membutuhkan kode yang sama, pindahkan kode tersebut ke bawah ke dalam modul inti.
  • Jika sebuah modul mengerjakan terlalu banyak hal yang tidak berkaitan, pecahlah modul tersebut.

Opsional: Pemisahan api dan impl

Aplikasi besar terkadang memisahkan sebuah fitur menjadi :feature:profile:api publik (antarmuka, rute navigasi) dan :feature:profile:impl privat (layar, model-tampilan). Fitur lain hanya bergantung pada api yang kecil, bukan pada implementasinya.

Ini adalah teknik tingkat lanjut; untuk sebagian besar aplikasi, satu modul untuk setiap fitur sudah lebih dari cukup. Anda cukup mengetahui bahwa pola ini tersedia untuk basis kode yang sangat besar.

// Other features see only the contract, not the screens
// feature/home depends on :feature:profile:api
interface ProfileEntry {
    val route: String
    fun NavGraphBuilder.register(navController: NavController)
}

Menyatukan Graf

Berikut cara lapisan-lapisan tersebut terhubung dalam contoh kita. Perhatikan bahwa dependensi hanya mengarah ke bawah: app -> feature -> data -> network/database -> model.

// :app           -> :feature:home, :feature:profile
// :feature:home  -> :core:data, :core:designsystem
// :feature:profile -> :core:data, :core:designsystem
// :core:data     -> :core:network, :core:database, :core:model
// :core:network  -> :core:model
// :core:database -> :core:model
// :core:model    -> (nothing)

Pemeriksaan Singkat

Modul :feature:home dan :feature:profile Anda sama-sama perlu mengambil dan menyimpan sementara data pengguna. Di mana kode repositori tersebut seharusnya berada?

Rangkuman: Modul Fitur dan Inti

Anda telah mempelajari cara membagi kode menjadi dua lapisan:

  • Modul fitur adalah potongan vertikal (layar + ViewModel + status UI).
  • Modul inti adalah kemampuan horizontal (model, jaringan, basis data, data, sistem desain).
  • Modul :app tetap tipis dan hanya merakit fitur.
  • Kode bersama dipindahkan ke bawah ke dalam inti; :core:model tetap bebas dari Android dan ringan.

Selanjutnya, Anda akan mengelola dependensi antarmodul ini dan menjaga agar graf tetap rapi.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Modul Fitur dan Inti” gratis?

Ya — teks lengkap “Modul Fitur dan Inti” 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 “Modul Fitur dan Inti”?

Tetapkan batas modul. 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 2 dari 4.

Berapa lama pelajaran “Modul Fitur dan Inti” 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