1 委托模式简介
委托模式的类图结构如下。
对应的 Kotlin 代码如下。
fun main() {var baseImpl = BaseImpl()var baseWrapper = BaseWrapper(baseImpl)baseWrapper.myFun1() // 打印: BaseImpl, myFun1baseWrapper.myFun2() // 打印: BaseImpl, myFun2
}interface Base {fun myFun1()fun myFun2()
}class BaseWrapper(var baseImpl: Base): Base {override fun myFun1() {baseImpl.myFun1()}override fun myFun2() {baseImpl.myFun2()}
}class BaseImpl: Base {override fun myFun1() {println("BaseImpl, myFun1")}override fun myFun2() {println("BaseImpl, myFun2")}
}
2 类委托
Kotlin 可以简化 BaseWrapper,简化后的代码如下。
fun main() {var baseImpl = BaseImpl()var baseWrapper = BaseWrapper(baseImpl)baseWrapper.myFun1() // 打印: BaseImpl, myFun1baseWrapper.myFun2() // 打印: BaseImpl, myFun2
}interface Base {fun myFun1()fun myFun2()
}class BaseWrapper(var baseImpl: Base): Base by baseImplclass BaseImpl: Base {override fun myFun1() {println("BaseImpl, myFun1")}override fun myFun2() {println("BaseImpl, myFun2")}
}
3 属性委托
3.1 by T
import kotlin.reflect.KPropertyfun main() {var str: String by StringDelegate()str = "abc"println(str)
}class StringDelegate {var value: String? = nulloperator fun getValue(thisRef: Any?, property: KProperty<*>): String {println("getValue, thisRef=$thisRef, name=${property.name}, value=$value")return value ?: throw IllegalStateException("Property not initialized")}operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {println("setValue, thisRef=$thisRef, name=${property.name}, value=$value")this.value = value}
}
打印日志如下。
setValue, thisRef=null, name=str, value=ABC
getValue, thisRef=null, name=str, value=ABC
ABC
3.2 by lazy
fun main() {// lazy为生成的委托对象, 获取属性时会执行lazy里面的操作, 只支持val变量val str: String by lazy { "666" }println(str) // 打印: 666
}
3.3 by Delegates.observable
fun main() {var str: String by Delegates.observable("666") { prop, old, new ->println("prop=$prop, old=$old, new=$new")}println(str) // 666// prop=property str (Kotlin reflection is not available), old=666, new=888str = "888"
}
3.4 by ::T
fun main() {var example = Example("ABC")example.str2 = "DEF"// str1=DEF, str2=DEFprintln("str1=${example.str1}, str2=${example.str2}")
}class Example(var str1: String) {var str2: String by ::str1
}
说明:属性被委托后,str1 和 str2 同时修改。
3.5 by map
fun main() {var map: MutableMap<String, Any> = mutableMapOf("name" to "Tom","age" to 23,"id" to 1001)var user = User(map)println(user) // (Tom, 23, 1001)
}class User(map: MutableMap<String, Any>) {var name: String by mapvar age: Int by mapvar id: Int by mapoverride fun toString(): String = "($name, $age, $id)"
}