分布式系统中的解耦模式:隔离事件层 - mathiasverraes


这是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等事件与私有流中同名事件也略有不同。
我们可以通过为每个消费者(例如客户通知系统,销售部门,运输公司等)制作单独的适配器,流和语言来进一步采用此示例。