- 领域驱动设计(Thoughtworks洞见)
- ThoughtWorks中国
- 650字
- 2020-06-25 10:30:58
让“DDD战略设计”指导隔离实施
实施战略设计时候,有一个重要的实践是限界上下文的识别,当存在多个限界上下文的时候,很有可能需要集成,防腐层是常见的集成手段。来看这个示意:Service A是左侧限界上下文暴露出来的接口,通过适配器调用右侧限界上下文的接口。

防腐层
这是不是很眼熟?这不正是端口和Driven Adapter吗?你可以认为它们是一种特化的防腐层。那么当一个单体应用中有多个限界上下文时,它们之间也应该用端口隔离,用适配器集成。如果你使用微服务来隔离限界上下文,端口和适配器架构则适用于其中每个服务。
回到DDD Cruise,还记得我们需要集成Headless CMS吗,由于在当前阶段,我们工作在单体应用中,CruiseSearch的API需要返回包含邮轮描述的信息。

没有识别限界上下文,虽然引入了端口和Driven Adapter,但不够理想。
一种方案是将这些描述信息加入到领域模型中,由于已有的两个数据源都无法提供这些信息,我们又引入了ContentfulCruiseSource及另一个出口端口CruiseContentEnricher及其Driven Adapter以便填充这些信息。但这个方案不够理想:
1.在邮轮搜索的筛选实现中,描述信息并没有实际作用,领域模型变得更臃肿了,甚至造成了干扰。
2.在邮轮搜索的测试中,我们并不关心这些描述信息,但却可能需要构造一些Dummy数据,避免可能的空指针误报。

将限界上下文引入DDD Cruise
在限界上下文概念指导下的另一种方案,引入CruiseContentEnricher既作为入口端口、同时也作为出口端口,保持邮轮搜索上下文不被干扰,这个方案的好处是,假设邮轮搜索引擎进行微服务改造,很有可能将描述信息填充的职责分离到单独的服务中去,这时,只需要再提供一个输入、输出不含描述信息的Driving Adapter就可以了。

在限界上下文指导下找到更稳定的端口