저번에도 Delegate 관련 개념에 대해서 알아보았지만 이번에는 그때 알아보지 못한 overvable과 vetoable에 대해 알아보려 한다.
어떠한 기능을 자기 자신이 처리하지 않고 다른 객체에 일을 위임시켜 그 객체가 일을 처리하게끔 하도록 하는 디자인 패턴을 Delgate Pattern 이라고 한다.
어떤 데이터의 값이 변경되었는지 쉽게 알아 낼 수 있도록하는 delegate 개념이다.
옵저버 패턴과 비슷하다고 볼 수 있다.
말 그대로 프로퍼티를 observable하게 만들어 주는 것이다.
프로퍼티의 데이터가 변할 때마다 callback을 받을 수 있는 구조이다.
public inlinie fun <T> observable(initialValue: T,
crossinline onChange: (property: KProperty<*>,
oldValue: T,
newValue: T) -> Unit): ReadWriteProperty<Any?, T>
= object : ObservableProperty<T>(initialValue) {
override fun afterChange(property: KProperty<*>,
oldValue: T,
newValue: T)
= onChange(property, oldValue, newValue)
}
var observableField: Int by Delegates.ovservable(0) { property, old, new ->
println("old: $old, new: $new")
}
fun main() {
println(observableField) // 0
observableField = 1
println(observableField) // 1
}
결과
0
old: 0, new: 1
1
observable과 거의 유사하지만 반환값이 존재한다.
public inline fun <T> vetoable(initialValue T,
crossinline onChange: (property: KProperty<*>,
oldValue: T,
newValue: T) -> Boolean) : ReadWriteProperty<Any?, T>
= object: ObservableProperty<T>(initialValue) {
override fun beforeChange(property: KProperty<*>, oldValue: T, newValue: T): Boolean
= onChange(property, oldValue, newValue)
}
vetoable 의 onChange 함수는 Boolean 값을 반환한다.
여기서 반환 값이 true 일 때만 프로퍼티의 값을 갱신한다.
var vetoableField: Int by Delegates.vetoable(0) { property, old, new ->
println("old: $old, new $new")
new % 2 == 0
}
fun main() {
println(vetoableField)
vetoableField = 1
println(vetoableField)
vetoableField = 2
println(vetoableField)
}
결과
0
old: 0, new: 1
0
old: 0, new: 2
2