Android mimarisi için öneriler

Bu sayfada Mimari ile ilgili çeşitli en iyi uygulamalar ve öneriler sunulmaktadır. Uygulamanızın kalitesini, dayanıklılığını ve ölçeklenebilirliğini iyileştirmek için bu özellikleri kullanın. Ayrıca, uygulamanızın bakımını ve testini de kolaylaştırırlar.

Aşağıdaki en iyi uygulamalar konuya göre gruplandırılmıştır. Her birinin, ekibin ne kadar güçlü önerdiğini gösteren bir önceliği vardır. Öncelik listesi aşağıdaki gibidir:

  • Kesinlikle önerilir: Yaklaşımınızla temel olarak çelişmediği sürece bu uygulamayı uygulamanız gerekir.
  • Önerilen: Bu uygulamayla muhtemelen uygulamanızı iyileştirebilirsiniz.
  • İsteğe bağlı: Bu uygulama, belirli durumlarda uygulamanızı iyileştirebilir.

Katmanlı mimari

Önerdiğimiz katmanlı mimarimiz, endişelerin giderilmesini destekler. Kullanıcı arayüzünü veri modellerinden alır, tek doğruluk kaynağı ilkesine uyar ve tek yönlü veri akışı ilkelerini izler. Katmanlı mimariyle ilgili en iyi uygulamalardan bazıları şunlardır:

Öneri Açıklama
Açıkça tanımlanmış bir veri katmanı kullanın.
Kesinlikle önerilir
Veri katmanı, uygulama verilerini uygulamanın geri kalanına gösterir ve uygulamanızın iş mantığının büyük bir kısmını içerir.
  • Yalnızca tek bir veri kaynağı içerseler bile depolar oluşturmalısınız.
  • Küçük uygulamalarda, veri katmanı türlerini bir data paketine veya modülüne yerleştirmeyi seçebilirsiniz.
Açıkça tanımlanmış bir kullanıcı arayüzü katmanı kullanın.
Kesinlikle önerilir
Kullanıcı arayüzü katmanı, uygulama verilerini ekranda görüntüler ve kullanıcı etkileşiminin birincil noktası olarak hizmet verir.
  • Küçük uygulamalarda, veri katmanı türlerini bir ui paketine veya modülüne yerleştirmeyi seçebilirsiniz.
Kullanıcı arayüzü katmanıyla ilgili diğer en iyi uygulamaları burada bulabilirsiniz.
Veri katmanı, veri deposu kullanan uygulama verilerini göstermelidir.
Kesinlikle önerilir

Kullanıcı arayüzü katmanındaki composables, etkinlikler veya ViewModels gibi bileşenler doğrudan bir veri kaynağıyla etkileşimde bulunmamalıdır. Veri kaynaklarına örnek olarak aşağıdakiler verilebilir:

  • Veritabanları, DataStore, SharedPreferences, Firebase API'leri.
  • GPS konum sağlayıcıları.
  • Bluetooth veri sağlayıcıları.
  • Ağ bağlantı durumu sağlayıcısı.
İlişkileri ve akışları kullanın.
Kesinlikle önerilir
Katmanlar arasında iletişim kurmak için eş yordamları ve akışları kullanın.

Eşliklerle ilgili diğer en iyi uygulamaları burada bulabilirsiniz.

Alan katmanı kullanın.
Büyük uygulamalarda önerilir
Birden çok ViewModel'de veri katmanıyla etkileşimde bulunan iş mantığını yeniden kullanmanız veya belirli bir ViewModel'in iş mantığı karmaşıklığını basitleştirmek istiyorsanız bir alan katmanı veya kullanım örnekleri kullanın.

kullanıcı arayüzü katmanı

Kullanıcı arayüzü katmanının rolü, uygulama verilerini ekranda görüntülemek ve kullanıcı etkileşiminin birincil noktası olarak hizmet etmektir. Kullanıcı arayüzü katmanıyla ilgili en iyi uygulamalardan bazıları şunlardır:

Öneri Açıklama
Çok Yönlü Veri Akışı (UDF) adımlarını uygulayın.
Kesinlikle önerilir
ViewModel'lerin, kullanıcı arayüzü durumunu gözlemci kalıbını kullanarak gösterdiği ve yöntem çağrıları aracılığıyla kullanıcı arayüzünden işlemler aldığı Çok Yönlü Veri Akışı (UDF) ilkelerini uygulayın.
Avantajları uygulamanız için geçerliyse AAC ViewModels'i kullanın.
Kesinlikle önerilir
İş mantığını işlemek için AAC ViewModels'i kullanın ve kullanıcı arayüzü durumunu kullanıcı arayüzünde (Compose veya Android Görünümleri) göstermek için uygulama verilerini getirin.

ViewModel ile ilgili diğer en iyi uygulamaları burada görebilirsiniz.

ViewModel'lerin avantajlarını burada inceleyin.

Yaşam döngüsüne duyarlı kullanıcı arayüzü durum toplama özelliğini kullanın.
Kesinlikle önerilir
Yaşam döngüsüne duyarlı uygun eş yordam oluşturucuyu kullanarak kullanıcı arayüzünden kullanıcı arayüzü durumlarını toplayın: Görünüm sisteminde repeatOnLifecycle ve Jetpack Compose'da collectAsStateWithLifecycle.

repeatOnLifecycle hakkında daha fazla bilgi edinin.

collectAsStateWithLifecycle hakkında daha fazla bilgi edinin.

Etkinlikleri ViewModel'den kullanıcı arayüzüne göndermeyin.
Kesinlikle önerilir
Etkinliği ViewModel'de hemen işleyin ve etkinliğin işlenmesinin sonucunda bir durum güncellemesine neden olun. Kullanıcı arayüzü etkinlikleri hakkında daha fazla bilgiyi burada bulabilirsiniz.
Tek etkinliklik uygulama kullanın.
Önerilir
Uygulamanızın birden fazla ekranı varsa ekranlar arasında gezinmek ve uygulamanıza derin bağlantı vermek için Gezinme Parçaları veya Gezinme Oluşturma özelliğini kullanın.
Jetpack Compose'u kullanın.
Önerilir
Telefonlar, tabletler, katlanabilir cihazlar ve Wear OS için yeni uygulamalar oluşturmak üzere Jetpack Compose'u kullanın.

Aşağıdaki snippet'te, kullanıcı arayüzü durumunun yaşam döngüsüne duyarlı bir şekilde nasıl toplanacağı özetlenmektedir:

Görüntüleme sayısı

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
                }
            }
        }
    }
}

Oluştur

@Composable
fun MyScreen(
    viewModel: MyViewModel = viewModel()
) {
    val uiState by viewModel.uiState.collectAsStateWithLifecycle()
}

ViewModel

ViewModels, kullanıcı arayüzü durumunu sağlamak ve veri katmanına erişim sağlamaktan sorumludur. ViewModel'lere ilişkin bazı en iyi uygulamaları burada bulabilirsiniz:

Öneri Açıklama
ViewModels, Android yaşam döngüsünden bağımsız olmalıdır.
Kesinlikle önerilir
ViewModels, Yaşam döngüsüyle ilgili hiçbir türe referans içermemelidir. Activity, Fragment, Context veya Resources öğelerini bağımlılık olarak iletmeyin. Bir şey ViewModel'de bir Context gerektiriyorsa bunun doğru katmanda olup olmadığını kesinlikle değerlendirmelisiniz.
İlişkileri ve akışları kullanın.
Kesinlikle önerilir

ViewModel, aşağıdakileri kullanarak verilerle veya alan adı katmanlarıyla etkileşimde bulunur:

  • Uygulama verilerini almak için Kotlin akışları,
  • viewModelScope ile işlem gerçekleştirmek için suspend işlevleri.
ViewModel'leri ekran düzeyinde kullanın.
Kesinlikle önerilir

ViewModel'leri yeniden kullanılabilir kullanıcı arayüzü parçalarında kullanmayın. ViewModels'i şu konumlarda kullanmalısınız:

  • Ekran düzeyinde besteler,
  • Görünümler'deki Etkinlikler/Parçalar,
  • Jetpack Navigasyon'u kullanırken hedefler veya grafikler.
Yeniden kullanılabilir kullanıcı arayüzü bileşenlerinde düz durum tutucu sınıflarını kullanın.
Kesinlikle önerilir
Yeniden kullanılabilir kullanıcı arayüzü bileşenlerindeki karmaşıklığı işlemek için düz durum tutucu sınıflarını kullanın. Bu sayede eyalet artırılıp harici olarak denetlenebilir.
AndroidViewModel kullanmayın.
Önerilir
AndroidViewModel yerine ViewModel sınıfını kullanın. Application sınıfı ViewModel'de kullanılmamalıdır. Bunun yerine, bağımlılığı kullanıcı arayüzüne veya veri katmanına taşıyın.
Bir kullanıcı arayüzü durumu gösterin.
Önerilir
ViewModels, verileri kullanıcı arayüzüne uiState adlı tek bir mülk aracılığıyla göstermelidir. Kullanıcı arayüzü birbiriyle alakasız birden fazla veri parçası gösteriyorsa sanal makine, birden fazla kullanıcı arayüzü durum özelliği gösterebilir.
  • uiState türünü StateFlow yapmanız gerekiyor.
  • Veriler hiyerarşinin diğer katmanlarından veri akışı olarak geliyorsa uiState öğesini, stateIn operatörünü WhileSubscribed(5000) politikasıyla (örnek) kullanarak oluşturmalısınız.
  • Veri katmanından veri akışı gelmeyen daha basit durumlarda, sabit StateFlow (örnek) olarak gösterilen bir MutableStateFlow kullanılması kabul edilir.
  • Veri, hata ve yükleme sinyalleri içerebilen bir veri sınıfı olarak ${Screen}UiState seçebilirsiniz. Bu sınıf, farklı eyaletler dışlayıcıysa mühürlü bir sınıf da olabilir.

Aşağıdaki snippet'te, bir ViewModel'den kullanıcı arayüzü durumunun nasıl gösterileceği özetlenmektedir:

@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
            )

    // ...
}

Yaşam döngüsü

Aşağıda Android yaşam döngüsüyle çalışmaya yönelik en iyi uygulamalardan bazıları verilmiştir:

Öneri Açıklama
Etkinlikler veya Parçalar'da yaşam döngüsü yöntemlerini geçersiz kılmayın.
Kesinlikle önerilir
Etkinlikler veya Parçalarda onResume gibi yaşam döngüsü yöntemlerini geçersiz kılmayın. Bunun yerine LifecycleObserver alanını kullanın. Uygulamanın, yaşam döngüsü belirli bir Lifecycle.State değerine ulaştığında çalışması gerekiyorsa repeatOnLifecycle API'yi kullanın.

Aşağıdaki snippet'te belirli bir Yaşam Döngüsü durumunda işlemlerin nasıl gerçekleştirileceği özetlenmektedir:

Görüntüleme sayısı

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) {
                // ...
            }
        }
    }
}

Oluştur

@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)
        }
    }
}

Bağımlılıkları yönetme

Bileşenler arasındaki bağımlılıkları yönetirken göz önünde bulundurmanız gereken birkaç en iyi uygulama vardır:

Öneri Açıklama
Bağımlılık ekleme yöntemini kullanın.
Kesinlikle önerilir
Bağımlılık yerleştirme ile ilgili en iyi uygulamalardan yararlanın. Bu en iyi uygulamalardan biri mümkün olduğunda yapı ekleme yöntemidir.
Gerektiğinde bir bileşeni kapsama alın.
Kesinlikle önerilir
Tür, paylaşılması gereken değişken veriler içeriyorsa veya tür ilk kullanıma hazırlama işlemi pahalıysa ve uygulamada yaygın olarak kullanılıyorsa bir bağımlılık kapsayıcısını kapsama alın.
Hilt'i kullanın.
Önerilir
Basit uygulamalarda Hilt veya manuel bağımlılık yerleştirme kullanın. Projeniz yeterince karmaşıksa Hilt'i kullanın. Örneğin, şunlara sahipseniz:
  • ViewModels ile birden fazla ekran—entegrasyon
  • WorkManager kullanımı: entegrasyon
  • Gezinme grafiğinin kapsamında yer alan ViewModels (entegrasyon) gibi Navigasyon'un gelişmiş kullanımı.

Test

Aşağıda test ile ilgili en iyi uygulamalardan bazıları verilmiştir:

Öneri Açıklama
Neleri test edeceğinizi bilmelidir.
Kesinlikle önerilir

Proje kabaca bir hello world uygulaması kadar basit değilse projeyi en azından şu öğelerle test etmelisiniz:

  • Akışlar dahil, birim testi ViewModels.
  • Birim testi veri katmanı varlıkları. Yani depolar ve veri kaynakları.
  • CI'da regresyon testi olarak yararlı olan kullanıcı arayüzü gezinme testleri.
Hileleri taklit etmek için sahte olanları tercih eder.
Kesinlikle önerilir
Daha fazla bilgi için Android dokümanlarında test ikililerini kullanma başlıklı makaleyi inceleyin.
StateFlow'u test edin.
Kesinlikle önerilir
StateFlow test edilirken:

Daha fazla bilgi için Android DAC'de test edilmesi gerekenler kılavuzu'na göz atın.

Modeller

Uygulamalarınızda modeller geliştirirken aşağıdaki en iyi uygulamaları dikkate almalısınız:

Öneri Açıklama
Karmaşık uygulamalardaki katman başına bir model oluşturun.
Önerilir

Karmaşık uygulamalarda, mantıklı olduğunda farklı katmanlarda veya bileşenlerde yeni modeller oluşturun. Aşağıdaki örnekleri inceleyin:

  • Uzak veri kaynağı, ağ üzerinden aldığı modeli yalnızca uygulamanın ihtiyaç duyduğu verileri kullanarak daha basit bir sınıfla eşleyebilir.
  • Kod depoları, yalnızca kullanıcı arayüzü katmanının ihtiyaç duyduğu bilgilerle DAO modellerini daha basit veri sınıflarıyla eşleyebilir.
  • ViewModel, UiState sınıfında veri katmanı modelleri içerebilir.

Adlandırma kuralları

Kod tabanınıza ad verirken aşağıdaki en iyi uygulamaları göz önünde bulundurmanız gerekir:

Öneri Açıklama
Adlandırma yöntemleri.
İsteğe bağlı
Yöntemler bir fiil ifadesi olmalıdır. Örneğin, makePayment().
Adlandırma özellikleri.
İsteğe bağlı
Özellikler bir isim ifadesi olmalıdır. Örneğin, inProgressTopicSelection.
Veri akışlarını adlandırma
İsteğe bağlı
Bir sınıf bir Akış akışı, LiveData veya başka bir akışı gösterdiğinde adlandırma kuralı get{model}Stream() olur. Örneğin, getAuthorStream(): Flow<Author> İşlev bir model listesi döndürürse model adı çoğul olmalıdır: getAuthorsStream(): Flow<List<Author>>
Adlandırma arayüzleri uygulamaları.
İsteğe bağlı
Arayüz uygulamalarına ilişkin adlar anlamlı olmalıdır. Daha iyi bir ad bulunamazsa Default önekini kullanın. Örneğin, NewsRepository arayüzü için OfflineFirstNewsRepository veya InMemoryNewsRepository kullanabilirsiniz. İyi bir ad bulamazsanız DefaultNewsRepository özelliğini kullanın. Sahte uygulamaların önüne Fake (FakeAuthorsRepository gibi) eklenmelidir.