Halaman ini menyajikan beberapa praktik terbaik dan rekomendasi Arsitektur. Gunakan keduanya untuk meningkatkan kualitas, keandalan, dan skalabilitas aplikasi. Alat ini juga memudahkan pemeliharaan dan pengujian aplikasi Anda.
Praktik terbaik di bawah ini dikelompokkan berdasarkan topik. Masing-masing memiliki prioritas yang mencerminkan seberapa kuat rekomendasi tim. Daftar prioritasnya adalah sebagai berikut:
- Sangat direkomendasikan: Anda harus menerapkan praktik ini kecuali jika pada dasarnya bertentangan dengan pendekatan Anda.
- Direkomendasikan: Praktik ini kemungkinan akan meningkatkan aplikasi Anda.
- Opsional: Praktik ini dapat meningkatkan aplikasi Anda dalam keadaan tertentu.
Arsitektur berlapis
Arsitektur berlapis yang kami rekomendasikan mendukung pemisahan fokus. Arsitektur ini mendorong UI dari model data, mematuhi satu sumber prinsip kebenaran, dan mengikuti prinsip aliran data searah. Berikut adalah beberapa praktik terbaik untuk arsitektur berlapis:
Rekomendasi | Deskripsi |
---|---|
Gunakan lapisan data yang ditetapkan dengan jelas.
Sangat disarankan |
Lapisan data mengekspos data aplikasi ke seluruh aplikasi dan berisi sebagian besar logika bisnis aplikasi Anda.
|
Gunakan lapisan UI yang jelas.
Sangat disarankan |
Lapisan UI menampilkan data aplikasi di layar dan berfungsi sebagai titik utama interaksi pengguna.
|
Lapisan data harus mengekspos data aplikasi menggunakan repositori.
Sangat disarankan |
Komponen di lapisan UI seperti composable, aktivitas, atau ViewModel tidak boleh berinteraksi langsung dengan sumber data. Contoh sumber data adalah:
|
Gunakan coroutine dan flow.
Sangat disarankan |
Gunakan coroutine dan flow untuk berkomunikasi antarlapisan. |
Menggunakan lapisan domain.
Direkomendasikan di aplikasi besar |
Gunakan lapisan domain, dalam kasus penggunaan, jika Anda perlu menggunakan kembali logika bisnis yang berinteraksi dengan lapisan data di beberapa ViewModels, atau ingin menyederhanakan kompleksitas logika bisnis ViewModel tertentu |
Lapisan UI
Peran lapisan UI adalah menampilkan data aplikasi di layar dan berfungsi sebagai titik utama interaksi pengguna. Berikut adalah beberapa praktik terbaik untuk lapisan UI:
Rekomendasi | Deskripsi |
---|---|
Ikuti Aliran Data Searah (UDF).
Sangat disarankan |
Ikuti prinsip-prinsip Aliran Data Searah (UDF), dengan ViewModels mengekspos status UI menggunakan pola observer dan menerima tindakan dari UI melalui panggilan metode. |
Gunakan ViewModels AAC jika manfaatnya berlaku untuk aplikasi Anda.
Sangat disarankan |
Gunakan ViewModels AAC untuk menangani logika bisnis, dan mengambil data aplikasi untuk mengekspos status UI ke UI (Compose atau Tampilan Android). |
Gunakan koleksi status UI yang mendukung siklus proses.
Sangat disarankan |
Kumpulkan status UI dari UI menggunakan builder coroutine berbasis siklus proses yang sesuai: repeatOnLifecycle di sistem View dan collectAsStateWithLifecycle di Jetpack Compose.
Baca selengkapnya tentang Baca selengkapnya tentang |
Jangan mengirim peristiwa dari ViewModel ke UI.
Sangat disarankan |
Proses peristiwa secara langsung di ViewModel dan menyebabkan pembaruan status dengan hasil penanganan peristiwa. Selengkapnya tentang peristiwa UI di sini. |
Gunakan aplikasi aktivitas tunggal.
Direkomendasikan |
Gunakan Navigation Fragment atau Navigation Compose untuk menavigasi antar-layar dan deep link ke aplikasi Anda jika aplikasi memiliki lebih dari satu layar. |
Gunakan Jetpack Compose.
Direkomendasikan |
Gunakan Jetpack Compose untuk mem-build aplikasi baru untuk ponsel, tablet, serta perangkat foldable dan Wear OS. |
Cuplikan berikut menguraikan cara mengumpulkan status UI dengan cara yang memperhitungkan siklus proses:
Views
class MyFragment : Fragment() {
private val viewModel: MyViewModel by viewModel()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect {
// Process item
}
}
}
}
}
Compose
@Composable
fun MyScreen(
viewModel: MyViewModel = viewModel()
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
}
ViewModel
ViewModels bertanggung jawab untuk menyediakan status UI dan akses ke lapisan data. Berikut adalah beberapa praktik terbaik untuk ViewModels:
Rekomendasi | Deskripsi |
---|---|
ViewModels seharusnya tidak bergantung pada siklus proses Android.
Sangat disarankan |
ViewModel tidak boleh menyimpan referensi ke jenis terkait Siklus Proses. Jangan teruskan Activity, Fragment, Context atau Resources sebagai dependensi.
Jika sesuatu memerlukan Context di ViewModel, Anda harus benar-benar mengevaluasi apakah hal tersebut dilakukan di lapisan yang tepat. |
Gunakan coroutine dan flow.
Sangat disarankan |
ViewModel berinteraksi dengan lapisan data atau domain menggunakan:
|
Menggunakan ViewModel pada tingkat layar.
Sangat disarankan |
Jangan gunakan ViewModel dalam potongan UI yang dapat digunakan kembali. Anda harus menggunakan ViewModel di:
|
Gunakan class holder status biasa dalam komponen UI yang dapat digunakan kembali.
Sangat disarankan |
Gunakan class holder status biasa untuk menangani kompleksitas dalam komponen UI yang dapat digunakan kembali. Dengan melakukan ini, status dapat diangkat dan dikontrol secara eksternal. |
Jangan gunakan AndroidViewModel .
Direkomendasikan |
Gunakan class ViewModel , bukan AndroidViewModel . Class Application tidak boleh digunakan di ViewModel. Sebagai gantinya, pindahkan dependensi ke UI atau lapisan data. |
Ekspos status UI.
Direkomendasikan |
ViewModel harus mengekspos data ke UI melalui satu properti yang disebut uiState . Jika UI menampilkan beberapa bagian data yang tidak terkait, VM dapat mengekspos beberapa properti status UI.
|
Cuplikan berikut menguraikan cara mengekspos status UI dari ViewModel:
@HiltViewModel
class BookmarksViewModel @Inject constructor(
newsRepository: NewsRepository
) : ViewModel() {
val feedState: StateFlow<NewsFeedUiState> =
newsRepository
.getNewsResourcesStream()
.mapToFeedState(savedNewsResourcesState)
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = NewsFeedUiState.Loading
)
// ...
}
Siklus Proses
Berikut adalah beberapa praktik terbaik untuk menggunakan siklus proses Android:
Rekomendasi | Deskripsi |
---|---|
Jangan mengganti metode siklus proses dalam Activity atau Fragment.
Sangat disarankan |
Jangan mengganti metode siklus proses seperti onResume dalam Activity atau Fragment. Sebagai gantinya, gunakan LifecycleObserver . Jika aplikasi perlu melakukan pekerjaan saat siklus proses mencapai Lifecycle.State tertentu, gunakan repeatOnLifecycle API. |
Cuplikan berikut menguraikan cara menjalankan operasi dengan status Siklus Proses tertentu:
Views
class MyFragment: Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onResume(owner: LifecycleOwner) {
// ...
}
override fun onPause(owner: LifecycleOwner) {
// ...
}
}
}
}
Compose
@Composable
fun MyApp() {
val lifecycleOwner = LocalLifecycleOwner.current
DisposableEffect(lifecycleOwner, ...) {
val lifecycleObserver = object : DefaultLifecycleObserver {
override fun onStop(owner: LifecycleOwner) {
// ...
}
}
lifecycleOwner.lifecycle.addObserver(lifecycleObserver)
onDispose {
lifecycleOwner.lifecycle.removeObserver(lifecycleObserver)
}
}
}
Menangani dependensi
Ada beberapa praktik terbaik yang harus Anda amati saat mengelola dependensi di antara komponen:
Rekomendasi | Deskripsi |
---|---|
Gunakan injeksi dependensi.
Sangat disarankan |
Gunakan praktik terbaik injeksi dependensi, terutama injeksi konstruktor jika memungkinkan. |
Cakupan ke komponen jika diperlukan.
Sangat disarankan |
Cakupan ke container dependensi saat jenis berisi data yang dapat berubah yang perlu dibagikan atau jenisnya mahal untuk diinisialisasi dan digunakan secara luas di aplikasi. |
Gunakan Hilt.
Direkomendasikan |
Gunakan Hilt atau injeksi dependensi manual di aplikasi sederhana. Gunakan Hilt jika project Anda cukup kompleks. Misalnya, jika Anda memiliki:
|
Pengujian
Berikut adalah beberapa praktik terbaik untuk pengujian:
Rekomendasi | Deskripsi |
---|---|
Ketahui yang harus diuji.
Sangat disarankan |
Kecuali jika project ini cukup sederhana seperti aplikasi hello world, Anda harus mengujinya, setidaknya dengan:
|
Lebih suka yang palsu daripada tiruan.
Sangat disarankan |
Baca selengkapnya di Menggunakan duplikat pengujian dalam dokumentasi Android. |
Uji StateFlow.
Sangat disarankan |
Saat menguji StateFlow :
|
Untuk informasi selengkapnya, lihat Panduan pengujian di DAC Android.
Model
Anda harus mengamati praktik terbaik ini saat mengembangkan model di aplikasi Anda:
Rekomendasi | Deskripsi |
---|---|
Buat model per lapisan di aplikasi yang kompleks.
Direkomendasikan |
Dalam aplikasi yang kompleks, buat model baru di berbagai lapisan atau komponen jika memungkinkan. Perhatikan contoh berikut:
|
Konvensi penamaan
Saat memberi nama codebase, Anda harus mengetahui praktik terbaik berikut:
Rekomendasi | Deskripsi |
---|---|
Penamaan metode.
Opsional |
Metode harus berupa frasa kata kerja. Misalnya, makePayment() . |
Penamaan properti.
Opsional |
Properti harus berupa frasa kata benda. Misalnya, inProgressTopicSelection . |
Penamaan aliran data.
Opsional |
Saat class mengekspos aliran data Flow, LiveData, atau aliran data lainnya, konvensi penamaan adalah get{model}Stream() . Misalnya, getAuthorStream(): Flow<Author>
Jika fungsi menampilkan daftar model, nama model harus dalam bentuk jamak: getAuthorsStream(): Flow<List<Author>> |
Penamaan implementasi antarmuka.
Opsional |
Nama untuk implementasi antarmuka harus bermakna. Gunakan Default sebagai awalan jika nama yang lebih baik tidak dapat ditemukan. Misalnya, untuk antarmuka NewsRepository , Anda dapat menggunakan OfflineFirstNewsRepository , atau InMemoryNewsRepository . Jika Anda tidak dapat menemukan nama yang bagus, gunakan DefaultNewsRepository .
Implementasi palsu harus diawali dengan Fake , seperti di FakeAuthorsRepository . |