分散式系統中的解耦模式:隔離事件層 - mathiasverraes

banq發表於2019-05-15

這是mathiasverraes領域事件系列文章最後一篇,其他可點選#領域事件 進入檢視!

使用可見性層明確分離不同有界上下文的事件,可以使用它們自己的語言。

問題

這個問題與顯式公共事件中描述的相同:有時將某些事件標記為公開是不夠的,您可能確實需要獨立演進內部的事件,同時以不同方式設計公共事件以適應外部客戶端。客戶端可能需要概要事件胖事件,但您不希望在滿足所有這些消費者客戶端需求的情況下卻使得你自己的有界上下文內部變得變得混亂。

還有一個問題是,如果太多的消費者將他們的需求強加給生產者,並且所有消費者都依賴於相同的事件,那麼消費者在邏輯上會彼此耦合。

解決

保持所有內部事件嚴格保密,設定一個偵聽內部事件的介面卡,並針對不同客戶端消費者發出不同的公共事件的新流。我們也可以為每個消費者設定一個單獨的介面卡和流,以高度適應他們的不同需要。

新事件流實際上是一個位於我們所處的不同的有界上下文裡:這些事件流有自己的語言、事件型別和名稱。這樣就可以通過構建反腐敗層進行事件的隔離,這也是防腐層的一個實現模式。

有些名稱可能與原來的有界上下文中的名稱重疊或衝突,但這很好:擁有在本地定義概念而不嘗試全域性定義概念的自由,這正是我們使用有界上下文的原因。

案例

在私有層中,我們發出:

OrderWasInitiated {orderId}
LineItemWasAdded {orderId, productId, quantity}
OrderWasPlaced {orderId, customerId}
StockWasReserved {orderId, stockId}
TransportWasBooked {transportId, orderId}
OrderWasPacked {orderId}
OrderWasShipped {orderId} 

介面卡是一種監聽這些事件的Projector,併為公共消費發出新流:

OrderWasPlaced {orderId, customerName, lineItems}
OrderWasConfirmed {orderId, customerName, lineItems}
OrderWasShipped {orderId, customerName, lineItems}

公共流明確為適合客戶而設計:OrderWasPlaced是一個概要事件,其他是胖事件,並且沒有完整性保證,因為stockId並且transportId不在該流中。

公共流是一個不同的有界上下文:公共流中的一些語言不存在於上述私有流中,如OrderWasConfirmed這個事件; 並且OrderWasPlaced與OrderWasShipped等事件與私有流中同名事件也略有不同。

我們可以通過為每個消費者(例如客戶通知系統,銷售部門,運輸公司等)製作單獨的介面卡,流和語言來進一步採用此示例。

 

相關文章