Kotlin, delegeli özellikler (delegated properties) için yerleşik bir destek sağlar. by mekanizması, herhangi bir özelliğin alıcısını veya ayarını belirli bir nesneye — delegaya devretmeyi sağlar. En bilinen delegatlar: lazy, observable, vetoable ve özel olanlardır.
Avantajlar:
Örnek bir kullanıcı delegesi:
class UpperCaseDelegate { private var value: String = "" operator fun getValue(thisRef: Any?, property: KProperty<*>): String = value operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: String) { value = newValue.uppercase() } } class Person { var name: String by UpperCaseDelegate() }
Sınırlamalar:
Android Context gibi bağlama erişimi gerektiren bir delegat, eşlik eden nesnelerde veya üst düzey nesnelerde kullanılabilir mi?
Sıklıkla "her zaman kullanılabilir, neden olmasın?" diye yanlış cevap verirler.
Doğru cevap: Hayır, çünkü companion nesneleri ve üst düzey nesneler, sınıf veya uygulama örneklerinin başlatılmasından önce başlatılır, bu da başlatılmamış bir bağlama erişimiyle ilgili hatalara yol açabilir. Örnek nesneye erişimi gerektiren delegeler yalnızca sınıf özelliklerinde kullanılmalıdır.
Hikaye
Android-ViewModel'de geçici başlatma delegasyonu: Bir programcı ağır-geçici delegayı eşlik eden nesneye çıkardı. Belirli durumlarda (SDK'nın güncellenmesinden sonra) uygulama, başlatma sırasında çökmesiyle sonuçlandı — bağlama henüz erişilebilir değildi, ancak delege zaten "init"'ini gerçekleştirmişti.
Hikaye
Delegelerle yanlış seri hale getirme: Verileri saklamak için özel bir delege kullanıldı, ancak bağlama ile seri hale getirilemeyecek referanslar içeriyordu. Seri hale getirme girişiminde hatalar ve veri kaybı oluştu.
Hikaye
Yanlış geri arama ile gözlemlenebilir delege: Geliştirici, durumu kontrol etmek için Delegates.observable kullandı, lambda içinde yeni bir değer ayarlandı ve bu da döngüye ve çalışma zamanı sırasında StackOverflowError'a yol açtı.