是否有更 DRY 的方式来使用 Kotlin Delegate 属性 observable?
Is there a more DRY way to use the Kotlin Delegate property observable?
我正在使用可观察模式来跟踪对象的变化。为此,我使用了来自 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")
}
}
有没有人有想法让这段代码更干,这样我就不必到处复制和粘贴这些行,我确实在网上看过但找不到在别处定义逻辑并应用它的方法class 中的所有属性。
您不需要显式地重新声明这样的方法。您可以很容易地在 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) {
我正在使用可观察模式来跟踪对象的变化。为此,我使用了来自 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")
}
}
有没有人有想法让这段代码更干,这样我就不必到处复制和粘贴这些行,我确实在网上看过但找不到在别处定义逻辑并应用它的方法class 中的所有属性。
您不需要显式地重新声明这样的方法。您可以很容易地在 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) {