Kotlin 的 Delegation

Evan Chen
Evan Android Note
Published in
May 12, 2022

在Design Pattern裡有一種pattern叫 Delegation pattern。是指物件將一個請求委派給另一個物件來處理

舉一個例子,ClassA 有一個功能叫sayHello()

今天有一個ClassB也要有這個sayHello的功能。讓ClassB去繼承ClassA當然就可以有這個功能,但這不是一個好的作法,因為ClassB只是想要有ClassAsayHello這個功能,卻要繼承整個ClassA的行為。我們應該多用組合,少用繼承。

比較好的方式就是用委派的方式,ClassB想要有sayHello這個功能,就請ClassA來幫忙做。ClassB仍可以對外說我有sayHello這個功能。

這樣寫還不夠好,因為ClassBClassA產生相依了。我們試著透過Interface來解相依。

  1. 建立一個 Interface 叫IHello,裡面有一個 function 叫sayHello
  2. ClassA 繼承IHello
  3. ClassB從constructor 傳入IHello
  4. ClassBsayHello呼叫IHello.sayHello

這樣我們就完成了使用 Delegation Pattern 來將一個物件要處理的事,委託給另一個物件。

而在 Kotlin,可以直接使用 by 這個關鍵字來表示委託給誰處理,ClassB就不用自已寫一個sayHello的 function。

你也可以override sayHello 這個 function。不過如果使用了override,被委派的ClassA裡的sayHello就不會再被執行了。

Delegate properties

你可以把一個 property 由 Delegate來處理,也就是這個 Delegate要來處理setter、getter的部分。

例如我們有一個 property 叫 name,在後面寫by Delegate表示委託給MyDelegate 這個Class來處理。

所以我們在MyDelegate這個 Class 就需要提供getValuesetValue的方法。因為property最主要的用法就是在做getValuesetValue

當你呼叫 example.name 時,就會由MyDelegategetValue來回傳值

當你使用example.name="new" 去給值的時候,就會由Delegate的setValue來處理,所以執行這段程式碼將會看到log:set new to 'name'

kotlin 既有的delegate properties

Lazy

lazy 就是一個 delegate,在第一次使用使才被初始化。

Observable

Observable 是當你設定屬性值時可以針對變更做處理。裡面的其中兩個參數old是變更前,new是變更後的值。

你也可以將屬性委託給另一個屬性,例如你有一個property:oldName已經棄用(Dprecated),但我們又不能直接把這個屬性刪掉,你可以直接委託給新的屬性newName

參考:

https://kotlinlang.org/docs/delegation.html

--

--