屬性委托本質(zhì)上就是代理模式
應(yīng)用參考:https://juejin.cn/post/7440362323992657956
- by
將某個屬性,委托給另一個對象進(jìn)行管理
將 Example 的 p 委托給 Delegate 進(jìn)行管理倒淫,通過操作符重載,實(shí)現(xiàn)自定義的 get/set 方法
class Delegate {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return "$thisRef, thank you for delegating '${property.name}' to me!"
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
println("$value has been assigned to '${property.name}' in $thisRef.")
}
}
class Example {
var p: String by Delegate()
// setter -> setValue
// getter -> getValue
}
fun main() {
val e = Example()
e.p = "AAA"
println(e.p)
}
- by lazy
為什么 lazy 里面沒有定義 get/set 方法镜硕,也可以使用 by 關(guān)鍵字實(shí)現(xiàn)屬性代理功能返干?
因?yàn)?lazy 內(nèi)部實(shí)現(xiàn)了一個擴(kuò)展函數(shù),并使用 operator 關(guān)鍵字實(shí)現(xiàn)了操作符重載财剖,所以能實(shí)現(xiàn)屬性代理的功能
class DelegatedProperty {
val friends by lazy {
loadFriendList()
}
private fun loadFriendList(): List<String> {
return listOf("pony", "johnny", "jack")
}
}
fun main(args: Array<String>) {
println(DelegatedProperty().friends)
}
- by Delegates.observable
open class PropertyChangeAware {
protected val changeSupport = PropertyChangeSupport("people")
fun addPropertyChangeListener(listener: PropertyChangeListener) {
changeSupport.addPropertyChangeListener(listener)
}
fun removePropertyChangeListener(listener: PropertyChangeListener) {
changeSupport.removePropertyChangeListener(listener)
}
}
class ObservableProperty2(
private var propValue: Int,
private val changeSupport: PropertyChangeSupport
) {
operator fun getValue(p: People3, pro: KProperty<*>): Int = propValue
operator fun setValue(p: People3, pro: KProperty<*>, newValue: Int) {
val oldValue = propValue
propValue = newValue
changeSupport.firePropertyChange(pro.name, oldValue, newValue)
}
}
class People3(val name: String, age: Int, salary: Int) : PropertyChangeAware() {
//通過by實(shí)現(xiàn)屬性委托躺坟,委托給ObservableProperty2
var age: Int by ObservableProperty2(age, changeSupport)
var salary: Int by ObservableProperty2(salary, changeSupport)
}
fun testImp3() {
val p3 = People3("AAA", 38, 74500)
p3.addPropertyChangeListener(PropertyChangeListener { event ->
//println("event source: ${event.source}")
println("Property ${event.propertyName} changed from ${event.oldValue} to ${event.newValue}")
})
p3.age += 1
p3.salary += 1000
}
fun main(args: Array<String>) {
testImp3()
}