Sealed class yapısı Kotlin’de olup Java’da olmayan ve Java’daki enum class yapısının bir üst modeli diyebileceğimiz bir yapıya sahiptir.
Öncelikle enum class yapısını hatırlayalım.
Örneğin sunucudan verileri alıyoruz ve bu verilerin durumunu bir enum yapısı ile tanımlamak istersek;
Java
1 2 3 4 5 |
public enum Resource { ERROR, LOADING, SUCCESS } |
Kotlin
1 2 3 4 5 |
public enum Resource { ERROR, LOADING, SUCCESS } |
Gördüğünüz gibi oldukça basit ve iki dil için de benzer yapıya sahipler.
Kullanımlarını da alttaki gibi yapabiliriz.
1 2 3 4 5 6 7 8 9 10 11 |
fun setState(resource: Resource) { when(resource) { Resource.ERROR -> { } Resource.LOADING -> { } Resource.SUCCESS -> { } } } fun showData(someData: SomeData) { } |
Üstte gördüğünüz gibi success durumunda 2 farklı metod çağrısı yapmamız gerekiyor. Bunlar setState
ve showData
metodları olacaktır. Bunu yapmamızın sebebi enumların data tutma konusundaki eksikliklerinden kaynaklıdır. Aslında data tutma kısmını alttaki gibi enum classa constructor tanımlayarak yapabiliriz.
1 2 3 4 5 |
enum class Resource(val someData: SomeData) { ERROR(SomeData(1, "test data 1")), LOADING(SomeData(2, "test data 2")), SUCCESS(SomeData(3, "test data 3")) } |
Ancak bu durumda şöyle bir sorunla karşı karşıyayız; Veriler her durumda elimize gelmiyor sadece SUCCESS durumunda bize geliyor. Diğer durumlar sadece o anlık durumu belirtiyor. Yani biz bu kodu çalıştırmak istediğimizde ERROR ve LOADING durumlarında bizden veri isteyecek ancak elimizde bir veri yok. Aslında bizim ihtiyacımız, her durumun farklı parametreler alabilmesi. İşte burada Sealed class kullanımı devreye giriyor.
Sealed class ile üst sınıf – alt sınıf hiyerarşisi kurabiliyorsunuz.
Örneğimizi şimdi sealed class kullanarak güncelleyelim.
1 2 3 4 5 |
sealed class Resource { class Error : Resource() class Loading : Resource() data class Success(val someData: SomeData) : Resource() } |
Gördüğünüz gibi Error ve Loading durumlarında herhangi bir veri almadık sadece durumu belirttik ancak Success durumu için sealed class içinde bir data class tanımlayarak constructor parametresi olarak datayı alabildik.
Eğer sealed class içinde herhangi bir veri alan durum yani tanımlanan class yoksa bunu kotlindeki object yapısı ile tanımlamak daha iyi olacaktır. Aslında onları singleton olarak tutmuş olacağız.
1 2 3 4 5 |
sealed class Resource { object Error : Resource() object Loading : Resource() data class Success(val someData: SomeData) : Resource() } |
Bu classın kullanımı da alttaki gibi olacaktır.
1 2 3 4 5 6 7 8 9 10 11 |
fun setState(resource: Resource) { when(resource) { is Resource.Error -> { } is Resource.Loading -> { } is Resource.Success -> { // verilere resource.someData şeklinde erişilebilir. // örneğin; textView.text = resource.someData.name } } } |
https://kotlinlang.org/docs/reference/sealed-classes.html