Learning Kotlin: the Observable Delegate
Want to learn more about types of delegates in Kotlin and how to use them? Check out this tutorial to learn more about using the observable delegate.
Join the DZone community and get the full member experience.
Join For FreeFollowing our introduction to the by
operator and delegates, this post looks at the second of the five built-in delegates, observable
.
The next built-in delegate is observable
. This allows us to intercept all attempts to set the value. You can do this with a setter, but remember you would need to duplicate that setter code every time. With the observable, you can build the logic once and reuse it over and over again.
Once again, let us start by looking at how we would do this without the delegated property:
class User() {
var name: String = "<NO VALUE>"
set(value) {
DataChanged("name", name, value)
}
var eyeColour: String = "<NO VALUE>"
set(value) {
DataChanged("eyeColour", name, value)
}
fun DataChanged(propertyName: String, oldValue: String, newValue: String) {
println("$propertyName changed! $oldValue -> $newValue")
}
}
fun main(args:Array<String>) {
val user = User()
user.name = "Robert"
user.eyeColour = "Green"
}
Note here that we need to do the setter twice manually, and in each one, we will need to change a value, which you know will get missed when you copy and paste the code.
In the next example, we change to use the observable
delegate, which allows us to easily call the same function.
While I don't recommend this for production, I did — in this example — call it in two different ways. For age
, as the second parameter is a lambda, I just created that and passed the parameters to my function. This is how all the demos normally show the usage of this. For name
though, since my function has the same signature as the lambda, I can pass it directly to the observable
, which seems much nicer to me. Though, since we need to pass a reference to our function, we need to prefix it with ::
.
package sadev
import kotlin.properties.Delegates
import kotlin.reflect.KProperty
class User() {
var name: String by Delegates.observable("<NO VALUE>", ::DataChanged)
var eyeColour: String by Delegates.observable("<NO VALUE>") { property, old, new ->
DataChanged(property, old, new)
}
fun DataChanged(property: KProperty<*>, oldValue: String, newValue: String) {
println("${property.name} changed! $oldValue -> $newValue")
}
}
fun main(args:Array<String>) {
val user = User()
user.name = "Robert"
user.eyeColour = "Green"
}
Published at DZone with permission of Robert Maclean, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments