Kotlin 的 Delegation
在Design Pattern裡有一種pattern叫 Delegation pattern。是指物件將一個請求委派給另一個物件來處理
舉一個例子,ClassA
有一個功能叫sayHello()
今天有一個ClassB
也要有這個sayHello
的功能。讓ClassB
去繼承ClassA
當然就可以有這個功能,但這不是一個好的作法,因為ClassB
只是想要有ClassA
的sayHello
這個功能,卻要繼承整個ClassA
的行為。我們應該多用組合,少用繼承。
比較好的方式就是用委派的方式,ClassB
想要有sayHello
這個功能,就請ClassA
來幫忙做。ClassB
仍可以對外說我有sayHello
這個功能。
這樣寫還不夠好,因為ClassB
與ClassA
產生相依了。我們試著透過Interface來解相依。
- 建立一個 Interface 叫
IHello
,裡面有一個 function 叫sayHello
ClassA
繼承IHello
ClassB
從constructor 傳入IHello
ClassB
的sayHello
呼叫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 就需要提供getValue
與setValue
的方法。因為property
最主要的用法就是在做getValue
與setValue
。
當你呼叫 example.name
時,就會由MyDelegate
的getValue
來回傳值
當你使用example.name="new"
去給值的時候,就會由Delegate的setValue
來處理,所以執行這段程式碼將會看到log:set new to 'name'
kotlin 既有的delegate properties
Lazy
lazy 就是一個 delegate,在第一次使用使才被初始化。
Observable
Observable 是當你設定屬性值時可以針對變更做處理。裡面的其中兩個參數old
是變更前,new
是變更後的值。
你也可以將屬性委託給另一個屬性,例如你有一個property:oldName
已經棄用(Dprecated),但我們又不能直接把這個屬性刪掉,你可以直接委託給新的屬性newName
參考: