10

領域驅動設計學習筆記(18):學DCI,重構Aggregate ,Part 3

 3 years ago
source link: https://teddy-chen-tw.blogspot.com/2021/06/18dciaggregate-part-3.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

領域驅動設計學習筆記(18):學DCI,重構Aggregate ,Part 3

June 24 16:20~17:14

ACtC-3ddR7ZQkIGp_ZFkk25labg1325fUhaPd8eTUIIAxM9DDsaBxSW6Nco99YVNZTw0nDEVpHjaN9VHeAOXGMPv3fMMXOoNtY05_Cnv6noG6FhvAiC-NXIj40qMFB9dhiZa6CiRmN5ETv3EgZCa_733mB55WQ=w1890-h1022-no?authuser=0

▲圖1 :在Aggregate Root身上增加這兩個方法以支援動態扮演角色的功能

前情提要

今天是表定介紹DCI與Aggregate連載的最後一集,談如何讓Aggregate具備動態扮演不同角色的能力

第一集Teddy提到在DDD的情境之下,Aggregate本身就是若干個小規模使用案例的集合體,所以實務上Teddy認為並不需要像DCI架構所建議的在不同的Context底下,讓Data object動態扮演不同的Role以執行不同功能。但為了學習目的,Teddy還是想辦法讓Aggregate具備這種動態扮演角色的能力。

透過Java Reflection實作

ezKanban後端以Java語言開發,Java是一個靜態型別語言,要讓物件動態扮演不同的角色,大概只能透過Reflection機制動手腳。

Teddy的想法很簡單,在Aggregate Root身上增加圖1的兩個方法:

  • mixinBehavior:把一個物件加入behaviors list裡面,這個物件可以是任意型別的物件。
  • playRole:想讓Aggregate扮演某個角色需要先把該角色透過mixinBehavior方法加入Aggregate Root,再呼叫playRole方法,傳入參數為扮演角色的類別,這樣就可以執行該角色身上的方法。請參考圖2。
ACtC-3frTCvjEUBgZDfpJZRiW9Yfg7uUFgfuQqfduaAsjs8q6iCFy1N0UR7z6nVuBdooaaNJ35TAXTOewzxe0arelDYpuWSKBkvAUCeVUHkr_yB5CSKPdePJuLSy-Pe2T1xcb7dbEJ6htHTSTaZH-D1ZAjiNDQ=w2206-h1580-no?authuser=0

▲圖2:測試案例,展示如何動態加入角色到Board Aggregate Root

以下解釋圖2程式碼:

  1. 宣告一個任意的類別叫做NewBehavior,它不用實作任何介面,就是一般的Java Class即可。它的身上有一個getBoardInfo方法,回傳一個board id 加上 board name所組合成的字串。這個類別需要獲得Aggregate Root的資料,因此它需要撰寫一個初始化的方法讓Aggregate Root呼叫,並且幫這個初始化方法貼上@MixinInitializer這個annotation。
  2. 呼叫board.mixBehavior,把newBehavior當成參數傳給board。這一行等於在程式執行期間動態指派一個角色給Board Aggregate。
  3. 呼叫board.playRole(NewBehavior.class)讓board扮演這個新的角色。
  4. 最後,可以呼叫到NewBehavior身上的getBoardInfo方法。
ACtC-3fITCauOxSmDltbAtX5GvPix0NgIuE__eh5wE4sYcxhcFic0vFJGnVWvnRWNbl0qlhQOI9v9zm0slE16qUEgHr_y9D9eyCOZGx2aoTN4ZEfQcOxiU6L1Un5JZUTW3AEmO7ijoaJtYJg0zJZZ4PCRrfZAg=w796-h210-no?authuser=0

▲圖3:測試案例執行結果,當然是綠燈通過

完整的程式還有不少細節Teddy沒有在這裡逐一解釋,不過大方向基本上就是上述的過程。

結論

DCI是一個很有趣的架構,而且可以和DDD與Clean Architecture一起使用,讓程式碼變得更乾淨,這是沒有問題的。

由於Aggregate Root實際上某種程度就是一個小的DCI,所以是否需要動態指派角色給它,Teddy目前還不是很確定是否有這個需要,為了學習的目的Teddy還是花了點時間完成這個功能。

最後,Teddy還在持續探討將DCI應用在更大的情境的可行性,例如在Saga pattern中使用DCI,等有結果之後再跟鄉民們分享。

友藏內心獨白:動態扮演角色真的滿酷的。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK