Alan adı katmanı, kullanıcı arayüzü katmanı ile veri katmanı arasında yer alan isteğe bağlı bir katmandır.
Alan adı katmanı, karmaşık iş mantığını veya birden fazla ViewModel tarafından yeniden kullanılan basit iş mantığını kapsamaktan sorumludur. Bu gereksinimler tüm uygulamalarda olmayacağından bu katman isteğe bağlıdır. Yalnızca gerektiğinde (örneğin, karmaşıklığı yönetmek veya yeniden kullanılabilirliği tercih etmek için) kullanmalısınız.
Alan adı katmanı aşağıdaki avantajları sağlar:
- Kodların yinelenmesini önler.
- Alan katmanı sınıflarının kullanıldığı sınıflarda okunabilirliği artırır.
- Uygulamanın test edilebilirliğini iyileştirir.
- Sorumlulukları bölmenize imkan tanıyarak büyük sınıfların oluşumunu önler.
Bu sınıfların basit ve küçük kalmasını sağlamak amacıyla, her kullanım alanı yalnızca tek bir işlev üzerinde sorumluluğa sahip olmalı ve değişken veriler içermemelidir. Bunun yerine, kullanıcı arayüzünüzde veya veri katmanlarınızda değişken verileri işlemeniz gerekir.
Bu kılavuzdaki adlandırma kuralları
Bu kılavuzda, kullanım alanları sorumlu oldukları tek işlemden sonra adlandırılmıştır. Sistem aşağıdaki gibidir:
mevcut zamandaki fiil + isim/ne (isteğe bağlı) + Kullanım alanı.
Örneğin: FormatDateUseCase
, LogOutUserUseCase
,
GetLatestNewsWithAuthorsUseCase
veya MakeLoginRequestUseCase
.
Bağımlılıklar
Tipik bir uygulama mimarisinde, kullanım alanı sınıfları, kullanıcı arayüzü katmanındaki ViewModel'ler ile veri katmanındaki depolar arasında yer alır. Bu, kullanım alanı sınıflarının genellikle depo sınıflarına bağlı olduğu ve geri çağırma (Java için) ya da eş kotinler (Kotlin için) kullanarak aynı şekilde depoların yaptığı şekilde kullanıcı arayüzü katmanıyla iletişim kurduğu anlamına gelir. Bu konu hakkında daha fazla bilgi için veri katmanı sayfasını inceleyin.
Örneğin, uygulamanızda, bir haber deposu ile bir yazar deposundan veri getiren ve bunları birleştiren bir kullanım alanı sınıfınız olabilir:
class GetLatestNewsWithAuthorsUseCase(
private val newsRepository: NewsRepository,
private val authorsRepository: AuthorsRepository
) { /* ... */ }
Kullanım alanları yeniden kullanılabilir mantık içerdiğinden, diğer kullanım alanları tarafından da kullanılabilir. Alan adı katmanında birden çok kullanım alanı düzeyine sahip olması normaldir. Örneğin, aşağıdaki örnekte tanımlanan kullanım alanı, kullanıcı arayüzü katmanındaki birden fazla sınıf ekranda doğru mesajı görüntülemek için saat dilimlerine ihtiyaç duyuyorsa FormatDateUseCase
kullanım alanından yararlanabilir:
class GetLatestNewsWithAuthorsUseCase(
private val newsRepository: NewsRepository,
private val authorsRepository: AuthorsRepository,
private val formatDateUseCase: FormatDateUseCase
) { /* ... */ }
Kotlin'de telefon araması kullanım alanları
Kotlin'de invoke()
işlevini operator
değiştiriciyle tanımlayarak kullanım alanı sınıfı örneklerini işlev olarak çağırılabilir hale getirebilirsiniz. Aşağıdaki örneğe bakın:
class FormatDateUseCase(userRepository: UserRepository) {
private val formatter = SimpleDateFormat(
userRepository.getPreferredDateFormat(),
userRepository.getPreferredLocale()
)
operator fun invoke(date: Date): String {
return formatter.format(date)
}
}
Bu örnekte, FormatDateUseCase
bölümündeki invoke()
yöntemi, sınıfın örneklerini işlevlermiş gibi çağırmanızı sağlar. invoke()
yöntemi, belirli bir imzayla sınırlı değildir. Herhangi bir sayıda parametre alıp herhangi bir türü döndürebilir. Ayrıca sınıfınızda invoke()
ürününe farklı imzalar ekleyebilirsiniz. Yukarıdaki örnekte verilen kullanım alanını aşağıdaki şekilde çağırırsınız:
class MyViewModel(formatDateUseCase: FormatDateUseCase) : ViewModel() {
init {
val today = Calendar.getInstance()
val todaysDate = formatDateUseCase(today)
/* ... */
}
}
invoke()
operatörü hakkında daha fazla bilgi edinmek için Kotlin belgelerine bakın.
Yaşam döngüsü
Kullanım alanlarının kendi yaşam döngüleri yoktur. Bunun yerine, kapsam, bunları kullanan
sınıflara ayarlanır. Yani kullanım alanlarını kullanıcı arayüzü katmanındaki sınıflar, hizmetler veya Application
sınıfının kendisinden çağırabilirsiniz. Kullanım alanlarının değişken veriler içermemesi gerektiğinden, bağımlılık olarak geçirdiğiniz her defasında kullanım alanı sınıfının yeni bir örneğini oluşturmanız gerekir.
İplik işleme
Alan katmanındaki kullanım alanları main-safe olmalıdır. Diğer bir deyişle, ana iş parçacığından çağrılmanın güvenli olması gerekir. Kullanım alanı sınıfları uzun süreli engelleme işlemleri gerçekleştiriyorsa bu mantığı uygun iş parçacığına taşımaktan sorumludur. Ancak bunu yapmadan önce, bu engelleme işlemlerinin hiyerarşinin diğer katmanlarına daha iyi yerleştirilip yerleştirilmeyeceğini kontrol edin. Genel olarak, yeniden kullanılabilirliği veya önbelleğe almayı teşvik etmek için veri katmanında karmaşık hesaplamalar gerçekleşir. Örneğin, büyük bir listedeki kaynak yoğun bir işlem, sonucun uygulamanın birden fazla ekranında yeniden kullanılması için önbelleğe alınması gerekiyorsa alan katmanı yerine veri katmanına daha iyi yerleştirilir.
Aşağıdaki örnekte, bir arka plan iş parçacığı üzerinde çalışan bir kullanım alanı gösterilmektedir:
class MyUseCase(
private val defaultDispatcher: CoroutineDispatcher = Dispatchers.Default
) {
suspend operator fun invoke(...) = withContext(defaultDispatcher) {
// Long-running blocking operations happen on a background thread.
}
}
Genel görevler
Bu bölümde, sık kullanılan alan adı katmanı görevlerinin nasıl gerçekleştirileceği açıklanmaktadır.
Yeniden kullanılabilir basit iş mantığı
Kullanım alanı sınıfında, kullanıcı arayüzü katmanında bulunan tekrarlanabilir iş mantığını özetlemeniz gerekir. Bu, mantığın kullanıldığı her yerde değişikliklerin uygulanmasını kolaylaştırır. Ayrıca, mantığı tek başına test etmenize de olanak tanır.
Daha önce açıklanan FormatDateUseCase
örneğini inceleyin. Tarih biçimlendirmeyle ilgili işletmenizin ihtiyaçları gelecekte değişirse kodu yalnızca tek bir merkezi yerden değiştirmeniz gerekir.
Depoları birleştirme
Bir haber uygulamasında, haber ve yazar verisi işlemlerini işleyen sırasıyla NewsRepository
ve AuthorsRepository
sınıflarınız olabilir. NewsRepository
tarafından sunulan Article
sınıfı yalnızca yazarın adını içerir ancak ekranda yazar hakkında daha fazla bilgi görüntülemek istiyorsunuz. Yazar bilgileri AuthorsRepository
adresinden elde edilebilir.
Mantık, birden çok depo içerdiği ve karmaşık hale gelebileceği için, mantığı ViewModel'den soyutlamak ve daha okunabilir hale getirmek için bir GetLatestNewsWithAuthorsUseCase
sınıfı oluşturursunuz. Bu, mantığın tek başına test edilmesini de kolaylaştırır ve uygulamanın farklı bölümlerinde yeniden kullanılabilir.
/**
* This use case fetches the latest news and the associated author.
*/
class GetLatestNewsWithAuthorsUseCase(
private val newsRepository: NewsRepository,
private val authorsRepository: AuthorsRepository,
private val defaultDispatcher: CoroutineDispatcher = Dispatchers.Default
) {
suspend operator fun invoke(): List<ArticleWithAuthor> =
withContext(defaultDispatcher) {
val news = newsRepository.fetchLatestNews()
val result: MutableList<ArticleWithAuthor> = mutableListOf()
// This is not parallelized, the use case is linearly slow.
for (article in news) {
// The repository exposes suspend functions
val author = authorsRepository.getAuthor(article.authorId)
result.add(ArticleWithAuthor(article, author))
}
result
}
}
Mantık, news
listesindeki tüm öğeleri eşler. Bu nedenle, veri katmanı ana güvenli olsa da, kaç öğe işleyeceğini bilmediğiniz için bu iş, ana iş parçacığını engellememelidir. Bu nedenle kullanım alanında, varsayılan görev dağıtıcıyı kullanarak iş bir arka plan iş parçacığına taşınır.
Diğer tüketiciler
Alan katmanı, kullanıcı arayüzü katmanından ayrı olarak hizmetler ve Application
sınıfı gibi diğer sınıflar tarafından yeniden kullanılabilir. Dahası, TV veya Wear gibi diğer platformlar kod tabanını mobil uygulamayla paylaşıyorsa bu platformların kullanıcı arayüzü katmanları, alan katmanının yukarıda belirtilen tüm avantajlarından yararlanmak için kullanım alanlarını da yeniden kullanabilir.
Veri katmanı erişim kısıtlaması
Alan katmanını uygularken dikkat edilmesi gereken diğer bir nokta da, kullanıcı arayüzü katmanından veri katmanına doğrudan erişime izin vermeniz veya alan katmanındaki her şeyi zorunlu kılmanızdır.
Bu kısıtlamayı uygulamanın bir avantajı, kullanıcı arayüzünüzün alan katmanı mantığını atlamasını engellemesidir. Örneğin, veri katmanına yapılan her erişim isteğinde analiz günlüğü kaydı gerçekleştiriyorsanız bu kısıtlamayı uygulama, kullanıcı arayüzünüzün alan katmanı mantığını atlamasını engeller.
Bununla birlikte, muhtemelen önemli dezavantajı, veri katmanına sadece basit işlev çağrıları olduğunda bile kullanım alanları eklemenizi gerektirmesidir, bu da çok az fayda sağlayacak şekilde karmaşık hale getirebilir.
Kullanım alanlarını yalnızca gerektiğinde eklemek iyi bir yaklaşımdır. Kullanıcı arayüzü katmanınızın verilere neredeyse yalnızca kullanım alanları üzerinden eriştiğini tespit ederseniz verilere yalnızca bu şekilde erişmek mantıklı olabilir.
Sonuç olarak, veri katmanına erişimi kısıtlama kararı bireysel kod tabanınıza ve katı kuralları mı yoksa daha esnek bir yaklaşımı mı tercih ettiğinize bağlıdır.
Test
Genel test kılavuzu, alan katmanı test edilirken geçerlidir. Diğer kullanıcı arayüzü testlerinde, geliştiriciler genellikle sahte depolar kullanır. Bu nedenle, alan katmanını test ederken de sahte depolar kullanmak iyi bir uygulamadır.
Sana Özel
Aşağıdaki Google örnekleri, alan adı katmanının kullanımını göstermektedir. Bu kılavuzu inceleyerek örnekleri inceleyin:
Sizin için önerilenler
- Not: Bağlantı metni JavaScript kapalıyken gösterilir
- Veri katmanı
- Kullanıcı arayüzü durumu üretimi