Delegaty observable i vetoable
Reaguj na zmiany właściwości za pomocą observable i warunkowo je odrzucaj przy użyciu vetoable.
Delegaty observable i vetoable to bezpłatna lekcja Kotlin Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Kotlin Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Kotlin Academy zawiera 4 lekcji w sumie.
Powtórzenie dotyczące delegatów właściwości
Delegaty właściwości Kotlin pozwalają oddzielnemu obiektowi obsługiwać metody getValue i setValue. Delegates.observable i Delegates.vetoable to wbudowane delegaty z biblioteki standardowej.
import kotlin.properties.Delegates
var name: String by Delegates.observable("initial") { prop, old, new ->
println("${prop.name}: $old -> $new")
}
fun main() { name = "Alice"; name = "Bob" }Składnia observable
observable przyjmuje wartość początkową i wywołanie zwrotne uruchamiane po każdej zmianie; otrzymuje ono właściwość, starą wartość i nową wartość.
import kotlin.properties.Delegates
var score: Int by Delegates.observable(0) { _, old, new ->
println("Score changed from $old to $new")
}
fun main() {
score = 10
score = 25
score = 0
}Wywoływanie aktualizacji interfejsu
Delegaty observable świetnie nadają się do wywoływania odświeżenia interfejsu użytkownika po zmianie właściwości bazowej, bez konieczności pełnej konfiguracji LiveData.
import kotlin.properties.Delegates
class ViewModel {
var title: String by Delegates.observable("Loading") { _, _, new ->
println("Render: $new") // pretend this updates UI
}
}
fun main() {
val vm = ViewModel()
vm.title = "Home"
vm.title = "Settings"
}Składnia vetoable
vetoable wywołuje funkcję zwrotną przed przypisaniem. Jeśli funkcja zwrotna zwróci false, nowa wartość zostanie odrzucona, a stara pozostanie zachowana.
import kotlin.properties.Delegates
var age: Int by Delegates.vetoable(0) { _, old, new ->
new >= 0 // reject negative ages
}
fun main() {
age = 25; println(age) // 25
age = -1; println(age) // 25 (rejected)
age = 30; println(age) // 30
}Łączenie walidacji z vetoable
Należy użyć vetoable, aby wymuszać niezmienniki domenowe na poziomie właściwości bez zewnętrznej logiki walidacji.
import kotlin.properties.Delegates
var email: String by Delegates.vetoable("") { _, _, new ->
new.contains("@")
}
fun main() {
email = "user@example.com"; println(email) // set
email = "invalid"; println(email) // still previous
}Rejestrowanie zmian za pomocą observable
Należy użyć observable do rejestrowania audytowego: każda zmiana stanu będzie automatycznie zapisywana bez modyfikowania logiki biznesowej.
import kotlin.properties.Delegates
val log = mutableListOf<String>()
var status: String by Delegates.observable("IDLE") { _, old, new ->
log.add("$old -> $new")
}
fun main() {
status = "RUNNING"
status = "DONE"
println(log)
}observable w klasie
Oba delegaty działają wewnątrz ciał klas tak jak każda inna właściwość.
import kotlin.properties.Delegates
class Counter {
var count: Int by Delegates.observable(0) { _, old, new ->
if (new > old) println("Incremented to $new")
else println("Decremented to $new")
}
}
fun main() {
val c = Counter()
c.count = 5
c.count = 3
}vetoable do ograniczania zakresu
Należy ograniczyć właściwość numeryczną do prawidłowego zakresu za pomocą vetoable.
import kotlin.properties.Delegates
var volume: Int by Delegates.vetoable(50) { _, _, new ->
new in 0..100
}
fun main() {
volume = 80; println(volume) // 80
volume = 150; println(volume) // 80 (rejected)
volume = 0; println(volume) // 0
}Łączenie delegatów
Logikę observable można łączyć ręcznie, pisząc własny delegat, który wewnętrznie wywołuje observable i dodaje dodatkową logikę na każdym etapie.
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
class LoggedDelegate<T>(initial: T) : ReadWriteProperty<Any?, T> {
private var value: T = initial
override fun getValue(t: Any?, p: KProperty<*>) = value
override fun setValue(t: Any?, p: KProperty<*>, v: T) {
println("Setting ${p.name} = $v"); value = v
}
}
var x: Int by LoggedDelegate(0)
fun main() { x = 10; x = 20 }Uwaga dotycząca bezpieczeństwa wątkowego
Żaden z delegatów observable i vetoable nie jest domyślnie bezpieczny wątkowo. W przypadku współbieżnego dostępu należy chronić modyfikacje za pomocą Mutex albo synchronizować je zewnętrznie.
import kotlin.properties.Delegates
// Not thread-safe as-is:
var sharedState: String by Delegates.observable("start") { _, old, new ->
println("$old -> $new")
}
// In coroutines, wrap access with Mutex if neededPraktyczny wzorzec: walidacja formularza
Należy użyć vetoable dla każdego pola w deklaratywnej walidacji formularza: każde pole samo sprawdza poprawność podczas przypisywania.
import kotlin.properties.Delegates
data class Form(
var username: String = "",
var password: String = ""
) {
var validUsername: String by Delegates.vetoable("") { _,_,v -> v.length >= 3 }
var validPassword: String by Delegates.vetoable("") { _,_,v -> v.length >= 8 }
}
fun main() {
val f = Form()
f.validUsername = "ab"; println(f.validUsername) // ""
f.validUsername = "alice"; println(f.validUsername) // "alice"
f.validPassword = "short"; println(f.validPassword) // ""
f.validPassword = "secure123";println(f.validPassword) // "secure123"
}Szybkie sprawdzenie
Kiedy vetoable wywołuje swoją funkcję zwrotną?
Podsumowanie
observable powiadamia po każdej zmianie, a vetoable działa przed przypisaniem i może odrzucić nową wartość. Oba delegaty świetnie nadają się do rejestrowania, walidacji i reaktywnych wzorców właściwości bez zewnętrznych bibliotek.
Często zadawane pytania
Czy lekcja „Delegaty observable i vetoable” jest bezpłatna?
Tak — pełny tekst „Delegaty observable i vetoable” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Kotlin Academy, przejdź na CoddyKit PRO. Kurs Kotlin Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Delegaty observable i vetoable”?
Reaguj na zmiany właściwości za pomocą observable i warunkowo je odrzucaj przy użyciu vetoable. Ćwiczysz Kotlin Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Kotlin Academy?
Nie wymagamy żadnego doświadczenia. Kotlin Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „Delegaty observable i vetoable”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Kotlin Academy?
Tak. Każda lekcja Kotlin Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- by lazy: szczegółowe omówienie odroczonej inicjalizacji
- Delegaty observable i vetoable
- Pisanie własnego delegata ReadWriteProperty
- Delegaty dla Preferences, właściwości opartych na Map i logowania