Estoy tratando de construir una clase en la que ciertos valores son Observables, sino también Serializable.
Obviamente, esto funciona y la serialización de las obras, pero es muy repetitivo, pesado tener que agregar un setter para cada campo y manualmente tener que llamar change(...)
dentro de cada setter:
interface Observable {
fun change(message: String) {
println("changing $message")
}
}
@Serializable
class BlahVO : Observable {
var value2: String = ""
set(value) {
field = value
change("value2")
}
fun toJson(): String {
return Json.encodeToString(serializer(), this)
}
}
println(BlahVO().apply { value2 = "test2" })
correctamente los productos
changing value2
{"value2":"test2"}
He intentado introducir a los Delegados:
interface Observable {
fun change(message: String) {
println("changing $message")
}
@Suppress("ClassName")
class default<T>(defaultValue: T) {
private var value: T = defaultValue
operator fun getValue(observable: Observable, property: KProperty<*>): T {
return value
}
operator fun setValue(observable: Observable, property: KProperty<*>, value: T) {
this.value = value
observable.change(property.name)
}
}
}
@Serializable
class BlahVO : Observable {
var value1: String by Observable.default("value1")
fun toJson(): String {
return Json.encodeToString(serializer(), this)
}
}
println(BlahVO().apply { value1 = "test1" })
activa correctamente la detección de cambio, pero no serializar:
changing value1
{}
Si me voy de Observables a ReadWriteProperty,
interface Observable {
fun change(message: String) {
println("changing $message")
}
fun <T> look(defaultValue: T): ReadWriteProperty<Observable, T> {
return OP(defaultValue, this)
}
class OP<T>(defaultValue: T, val observable: Observable) : ObservableProperty<T>(defaultValue) {
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
super.setValue(thisRef, property, value)
observable.change("blah!")
}
}
}
@Serializable
class BlahVO : Observable {
var value3: String by this.look("value3")
fun toJson(): String {
return Json.encodeToString(serializer(), this)
}
}
el resultado es el mismo:
changing blah!
{}
Del mismo modo para los Delegados.vetoable
var value4: String by Delegates.vetoable("value4", {
property: KProperty<*>, oldstring: String, newString: String ->
this.change(property.name)
true
})
salidas:
changing value4
{}
Los delegados simplemente no parece funcionar con Kotlin Serialización
¿Qué otras opciones existen para observar de una propiedad, los cambios sin romper su serialización que también funciona en otras plataformas (KotlinJS, KotlinJVM, Android, ...)?