我正在使用可观察的模式来跟踪对象中的更改。为此,我使用了Kotlin的observable中的构建。一切对我来说都很好,但是为了跟踪某些更改,我必须为每个属性重复相同的代码。这是我的代码:
class Employee(
id: String,
name: String,
surname: String,
age: Int,
salary: Int) {
val changes = HashMap<String, Pair<Any, Any>>()
val id = id //Id is immutable
var name: String by Delegates.observable(name) { prop, old, new ->
if (old != new) {
changes.put(prop.name, Pair(old, new))
println("${prop.name} has changed from $old to $new")
}
}
var surname: String by Delegates.observable(surname) { prop, old, new ->
if (old != new) {
changes.put(prop.name, Pair(old, new))
println("${prop.name} has changed from $old to $new")
}
}
var age: Int by Delegates.observable(age) { prop, old, new ->
if (old != new) {
changes.put(prop.name, Pair(old, new))
println("${prop.name} has changed from $old to $new")
}
}
var salary: Int by Delegates.observable(salary) { prop, old, new ->
if (old != new) {
changes.put(prop.name, Pair(old, new))
println("${prop.name} has changed from $old to $new")
}
}
}
如您所见,我为每个属性重复以下代码行:
by Delegates.observable(name) { prop, old, new ->
if (old != new) {
changes.put(prop.name, Pair(old, new))
println("${prop.name} has changed from $old to $new")
}
}
没有人有想法使此代码更干燥,这样我就不必在各处复制和粘贴行了,我的确在网上看过,但是找不到一种方法来定义其他地方的逻辑并适用于所有人类中的属性。
答案 0 :(得分:1)
您不需要显式重新声明这样的方法。您可以很轻松地在Kotlin中传递方法引用。因此,您可以这样做:
val age = Delegates.observable(age, ::handler) // Notice `::handler`
// repeat for the others...
// And this is the actual function:
fun handler(prop: KProperty<*>, old: Any, new: Any){
if (old != new) {
changes.put(prop.name, old to new)
println("${prop.name} has changed from $old to $new")
}
}
::handler
将方法引用传递给处理所有方法的方法。您仍然需要重复初始化,但是不需要多次创建相同的处理程序方法。
此外,如果id
是一个val,并且您不对其进行任何操作,则可以执行以下操作:
class Employee(
val id: String, // Adding `val` or `var` in the constructor makes it an actual variable, instead of just local to the constructor. ***NOTE:*** This only applies to primary constructors.
name: String,
surname: String,
age: Int,
salary: Int) {