前言
這篇稍微紀錄一下這次讀本書第十一篇的感想,這篇想記錄EventBus,讀寫分離後,讀變得相對簡單了,但寫會推薦使用EventBus/CommandBus的方式,讀跟寫也是使用不同的資料源
Agenda
- EventBus
事件源 EventBus
在這裡還是要補上這張圖,架構大概也就是這樣,為啥要使用EventBus,在第八章其實有說道在很常變化的邏輯上,使用Domain Event可以降低程式碼的複雜度,但你得先懂得如何使用。這邊想歸類幾個必要的東西:
- Base
- EventBus.cs
- EventHandler
- SendEmailEventHandler.cs
- SendMessageEventHandler.cs
- EventData
- ImportItemsEventData.cs
- Interface
- IEventBus.cs
- IEventData.cs
- IEventHandler.cs
- IEventStore.cs
- EventStore
- InMemoryEventStore.cs
EventStore跟EventBus
最主要的就是EventBus.cs,裡面會有基本的Subscribe,UnSubscribe,Publish這三個方法,可以更多但一定會有這三個,名稱當然可以不同,不過就是要Subscribe註冊,註冊你的事件跟處理這事件的handler,還有就是觸發Publish。你可以註冊到In Memory的原件例如Dictionary<Type, List
EventData跟EventHandler
再來你會需要製作EventData,有的人使用xxxEvent,我的後贅詞我使用EventData。裡面大部分會有的就是Id,透過這個來做處理。我使用ImportItemsEventData類來作當我進了一批貨,在我的Service層會去觸發Import該Items的數量,完成後我會使用EventBus.Publish()方法去觸發有註冊到ImportItemsEventData的Handler。這裡我建立了兩個Handler: SendEmailEventHandler.cs跟SendMessageEventHandler.cs。 一個是執行Email寄送,一個是傳送訊息。你一定要IEventHandler讓你的handler繼承,裡面會有一個方法,這方法內就是該hanlder要執行的邏輯。另一個是IEventData,你可能想問為什麼需要這兩個Interface,因為會需要對應,而透過interface方式你才可以抽象化,不然你綁太緊你很難抽換。
IOC初始化你的類
最後要講到怎麼對應,以前我們會用XML,把EventData寫出來,跟他會用到的Handler寫出來,在程式碼一開始時候initailize(),建立對應。我的範例就是ImportItemEventData會對應到SendMessageEventHandler跟SendMailEventHandler兩個。所以當我使用EventBus.Publish()觸發ImportItemEventData的時候,他會去EventBus內的EventStore的In Memory的Dictionary<Type, List
結論
- EventBus的優點在我認為上就是縮減複雜度,原本一個會員註冊的邏輯跟註冊完後的邏輯都是寫在一起的,但透過EventBus的方式可以抽離這些邏輯,後續修改上,可以依照顆粒度來修改,異動到同一個類同一個方法總是有風險的,如果可以拆分更細的方法到其他的類上,在修改上也比較符合開放封閉原則。本文也有說道,切忌不要濫用EventBus的方式,過度使用反而未必好維護,所有做架構最終目的都是希望後續好維護,而評估的考量當然還是回歸到團隊上。