iT邦幫忙

2023 iThome 鐵人賽

DAY 17
0
Kotlin

讓 Kotlin 程式碼更道地 - 談 Effective Kotlin 與相關的 Design Pattern系列 第 17

D17: Kotlin 重用性 - 使用屬性委託來提取常見的模式

  • 分享至 

  • xImage
  •  

Item 21: Use property delegation to extract common property pattern

Kotlin 的屬性委託

Kotlin 的屬性委託是一種強大的功能,用於提取和重用常見的屬性模式,可以用於支援程式碼的重用性。它為我們提供了一種通用的方式來提取常見的屬性行為。一個重要的例子是懶惰 (Lazy) 屬性 - 在其第一次使用時按才初始化的屬性。這樣的模式非常受歡迎,在不支持原生惰性屬性的語言中,每次需要時都必須執行一次 function, 可能會花費許多時間。在 Kotlin stdlib 中,有一個 lazy,該函數返回一個實現懶惰屬性模式的屬性委託:

val value by lazy { createValue() }

observable 屬性

lazy 不是唯一的屬性委托。另一個重要的例子是 observable 屬性 - 一個在屬性改變時做某事的屬性。例如,假設你有一個 list adapter 會重新畫出 list。每當其中的資料發生變化時,我們需要根據資料的改變重新畫出 list。就可以利用 observable 達到


var items: List<Item> by Delegates.observable(listOf()) { _, _, _ ->
    notifyDataSetChanged()
}

或者你可能需要記錄屬性的所有更改。也可以使用 observable 實現:

var key: String? by Delegates.observable(null) { _, old, new ->
    Log.e("key changed from $old to $new")
}

在上面的例子中,Delegates.observable 創建了一個具有觀察者功能的屬性。每次屬性的值被修改時,給定的 lambda 函數就會被調用。lambda 函數接收三個參數:一個是屬性的元數據(如名稱)、一個是舊值和一個是新值。

這是 observable 屬性委託的一個簡單例子,但實際上,您可以在該 lambda 函數中執行任何操作,如資料驗證、通知其他系統模組等。

observable 與 AOP

observable 會有點 Spring 中 AOP 的的味道,但有一個滿大的不同的是 AOP 是 runtime 時的解釋,相反的 observable 是在編譯期就決定,這增加了安全性與效能。

Votable

vetoable 是 Kotlin 的另一個有趣的屬性委託。與 observable 不同,vetoable 允許你根據某些條件接受或拒絕屬性的新值。如果 vetoable 中的 lambda 返回 true,則新值會被接受;如果返回 false,則新值會被拒絕,屬性值不會更改。

以下是一個使用 vetoable 的例子,其中我們有一個 age 屬性,並確保其值不會小於0:

import kotlin.properties.Delegates

class Person {
    var age: Int by Delegates.vetoable(0) { _, _, newValue ->
        // 只有當新值大於或等於0時,我們才接受該值
        newValue >= 0
    }
}

fun main() {
    val person = Person()
    println(person.age)  // Prints: 0

    person.age = 25
    println(person.age)  // Prints: 25

    person.age = -5
    println(person.age)  // Prints: 25, 因為 -5 小於 0, 所以值未改變
}

當我們嘗試將 age 設為一個小於 0 的值時,vetoable 會阻止其更改。

每日一推 G(I)-DLE

I'm the trend
Yes


上一篇
D16: 不要重造輪子,多認識好用的函式, 函式庫
下一篇
D18: 寫在 JCConf 前 - Coroutines vs Virtual Thread (Project Loom)
系列文
讓 Kotlin 程式碼更道地 - 談 Effective Kotlin 與相關的 Design Pattern30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言