DDD实践中如何设计上下文BC之间的映射关系?


如何区分产品基础设施和技术基础设施 :

  • 技术基础架构--不需要构建业务/产品背景,主要由开发人员使用。它不会立即影响用户体验,并且可以包含在一个特定的行会中。
  • 产品基础设施——影响用户体验或有产品需求。

平台组负责产品基础设施,而相关技术组负责技术基础设施。

  • 日志记录:属于技术基础架构,因为仅限开发人员要求
  • 身份验证:属于产品基础设施,是和用户体验。例如登录流程
  • Mongo 包装器:属于技术基础架构,仅限开发人员要求
  • 通过 DB进行数据隔离:属于产品基础设施,因为客户对安全的要求
  • 开放API:属于产品基础设施,因为是实现客户集成的核心组件

在本篇文章中,我将介绍与产品基础设施相关的通用技术。

什么是GBC(通用有界上下文)?
在DDD中,我们可以看到三种主要的子域类型。

但是在我们的Augury中,我们决定不使用子域的定义,以避免公司术语过多,因此我们选择只关注有界上下文BC。

有界上下文(BC)聚集了我们产品的相关领域和业务需求。
随着我们产品的发展,会有更多的BC诞生。

在DDD中,一个BC包含一个或多个Aggregates聚合。

有界上下文BC类型
由于我们避免添加子域,我们在系统中定义了不同类型的有界上下文

  1. 核心BC(魔力)--核心BC将包括使我们比其他公司更具竞争优势的业务逻辑。这种逻辑是我们Augury系统特有的,不能现成购买。
  2. 支持性BC(具有上下文的神奇推动力)--支持性BC将包括Augury专用的业务上下文。我们很可能选择自己实现它,因为Augury提供的核心功能需要它。
  3. 通用BC(无上下文的Magic enabler)--通用BC不包括Augury专用业务上下文,并且很可能可以作为现成产品购买。这是因为这些问题已经被其他领域的专家(公司)"解决 "了。

在我们的公司界限上下文映射中没有映射技术基础设施。

交叉服务
提醒--跨领域服务为系统中的不同聚合体提供常用功能。它在设计上并不面向特定的产品领域,而应能够支持各种集合完成其日常任务。

交叉服务是一种实用模式,它提供特定关注点的接口。

什么时候创建一个跨领域的交叉微服务:

  • 当我们需要提供一种重复的能力,而没有特定领域的专业知识时
  • 当我们发现自己的服务有许多依赖关系,而没有真正的业务领域原因时
  • 当我们需要提供独立部署的 "利用 "能力,以帮助其他服务完成其日常任务时

服务请求(Service Request)--用于激活交叉服务的某些流程或功能的请求。可通过Async事件或API调用实现。


神奇的构建与购买问题
在GBC中,购买现成产品的情况很普遍,因为别人已经解决了这些问题,而且这不是公司的差异化优势,因此我们希望减少在这些领域的工作量。
因此,我们在这些领域的思路是 "先买。只有在没有现成产品的情况下,才考虑自己制造"。

什么时候使用GBC?

  • 当有一个以上的消费者时->倾向于将第三方集成封装在交叉服务或软件包/中间件中。
  • 当需要添加大量的逻辑来支持我们的内部需求时-->使用GBC实用模式(如下所示),与交叉服务一起使用。

在本博文的实用模式中,我将提到我们需要在横向服务中封装第三方工具的情况。

依赖、关系和成熟度
为了能够定义GBC的实用模式,我研究了DDD是如何定义这些东西的--"依赖关系"、"关系 "和 "成熟度"。

  • 值得注意的是,依赖、关系和成熟度类型也可以在支持和核心子领域中找到。我是从泛型这一特定角度进行研究的,因为目前我的领域是平台。

BC依赖类型
我们首先需要了解与相关团队或BC的关系,以了解我们希望为GBC选择哪些实用的技术模式。

关系类型

  • 相互依赖 - 两个团队或有界上下文BC相互依赖,当他们的软件工件或系统需要一起交付才能成功和工作时。
  • 上游下游 - 上游团队的行为会影响下游团队,但下游团队的行为不会对上游团队产生重大影响。
  • 自由 - 如果其他有界上下文BC的变化不影响其成败,则BC或在这个BC中工作的团队是自由的。

什么是上下文BC映射?
上下文映射通过一系列模式来描述有边界的上下文和团队之间的关系,我们可以在以下关系类型之间进行映射

每一列中的每一个名称都代表了上下文映射中的一种模式。

BC成熟度
基础架构工作让我们这些技术人员开始考虑构建强大的、100%自助服务的系统。
尽管这很诱人,但在构建基础架构时,我们会逐渐希望成熟到最强大、最复杂的解决方案,特别是当它有多个消费者并需要服务于多个用例时。

以下是我所确定的三种主要成熟类型:

  1. Product
  2. 消费使用数量
  3. GBC复杂度

这些可以帮助我们了解GBC所处的状态,并帮助我们找到正确的实践模式。我们将利用这些特征来引导我们找到适合我们成熟度的相关模式。

GBC实用模式
在深入探讨这些模式之前,我想先总结一下我们目前所掌握的情况,以确保所有的点都能联系起来。

  • 我指的只是有产品需求的通用模式。
  • 有一种实用模式被称为 "交叉服务",它代表了一种您需要包装第三方工具的情况。
  • 在我们的案例中,相关的关系类型是 "上游-下游",相关的上下文映射模式是--客户-供应商、符合者、开放的主机服务和反腐败层。
  • 产品成熟度特征应表明BC的成熟度,并指明应选择哪种实用模式。


Customer supplier
Customer supplier 是最简单的模式,也是最不成熟的模式。类似架构中发布订阅模式

任何一方都可以决定这个接口,这表明,这种模式是最简单的,应该是我们实现新的GBC时的首选。

它可以帮助我们快速构建和学习,理解所需的需求。

这种模式最大的缺点是,当我们在映射层中添加越来越多的消费者时,我们将在过渡到符合模式时遇到更大的挑战。

因此,在使用这种模式时,要经常问问自己,你的BC何时已经成熟到可以迈出下一步了。

实用模式--生成一个交叉服务,如果需要的话,它可以容纳一个映射层,允许消费者使用服务,但不与之保持一致。

何时选择Customer supplier 客户供应商模式(使用成熟度特征)?

  • BC 成熟度上是良好,但不是可重复的
  • 跨团队协调性不需要太多

接口实现是异步消息总线。

Conformist
类似架构中直接API同步调用。

API提供者已经决定了接口,不需要映射转换层,消费者可以直接使用接口。

  • BC 成熟度上是良好,因为它是可重复的
  • 跨团队协调方面:需要传播和向后兼容性,需要团队协调。

接口可以是同步API(或异步消息总线)。


Open-host service
开放式主机服务模式与遵从型conformist服务模式的主要区别在于,它需要一个更复杂的接口(内部DSL)以

  • 提供转换引擎。
  • 生成大量的抽象,以支持众多消费者的需求。

构建一个好的DSL是一项艰巨的工作,假设我们在获得了一些消费者之后达到了这种复杂程度,我们预计需要一个迁移计划或向后兼容性,这意味着它可能是一项艰巨的工作。

我们应该认真考虑是否需要这样的复杂性,甚至考虑挑战要求我们这样做的产品决策。

  • BC 成熟度上需要很高,否则花费大量精力构建的DSL,如果BC不成熟,全部浪费。
  • 跨团队协调方面:需要传播和向后兼容性,需要团队协调。

反腐层
最后但并非最不重要的是反腐败层。这种模式不同于其他模式,因为它旨在帮助消费者使用新服务,同时避免将所有领域统一起来。在这种情况下,表格是多余的,因为成熟度、过渡性和devX由于变化成本而未被考虑。

实用模式--消费者将在现有或新组件中生成一个映射层。该层将消耗来自消费者的所有请求。

使用场景:

  • 与第三方供应商集成时。
  • 当调整消费者接口成本过高时。


总结
因为基础架构的构建非常困难,有许多依赖关系,而且我们希望尽可能地启用MVP思维。

我们希望开发出一套技能,以了解我们正在构建的服务(如电子邮件即服务)的成熟度。

在考虑构建一个为产品团队(而非开发人员)提供服务的通用基础架构时,我们需要生成正确的模式。

我们已经定义了一种横向跨领域服务,它是所有模式的基础。

一旦有了这个基础,我们就可以开始考虑它与公司中不同边界上下文的关系。

根据通用服务的成熟度及其复杂性,我们将选择一种特定的上下文映射模式,并将其转化为实用模式。