Skip to main content

多个上下文之间如何协作

上下文映射(Context Mapping)

  • 上下文映射是指限界上下文之间的模型映射关系
  • 描述团队之间的协作关系以及上下文之间的集成关系
  • 决定上下文之间如何集成以及如何设置防腐层

image-20240118220530077

所谓的依赖不仅仅指调用关系,调用关系只是其中的一个方面,更重要的是模型与模型之间的映射关系。

image-20240118221448306

不同限界上下文各自包含了一些关键概念,其中有一些重叠的概念,比如交易上下文和支付上下文都包含了支付二维码这个概念,交易上下文和设备上下文都包含了商品概念,这种现象是正常的,这就是限界上下文的意义所在。

但是在系统实现的过程中,我们需要处理一个问题,当集成两个概念重叠的限界上下文的时候,怎样处理这种重叠,是将其中一个转换成另一个或者多个,还是一个向另一个看齐。

这就是模型与模型之间的映射关系,这和团队之间的协作关系,以及上下文之间的集成关系是等价的。

当你要集成另一个上下文的时候,就意味着要看到它暴露出来的一些概念,比如说要集成一个商品中台,就要了解它传递过来的一些商品字段是什么意思,如果内部也有商品这个类,就需要把它提供的商品对象转换成内部可以用的商品对象,这就是一种比较常见的映射关系 ,这个时候就称商品中台上下文是上游

image-20240118221521643

上下文映射模式

image-20240118230217003

开放主机服务

现在开发系统,很多时候会借助一些第三方服务,包括云厂商的服务,或者内部中台,或者架构部门提供的成熟组件,这种服务和组件很多时候以公共 API 的方式暴露出来,这种以公共API 的方式提供的服务就叫做开放主机服务。

  • 服务提供方文所有消费方提供一套公共的 API
  • 针对通用的功能和模型

image-20240118222405325

服务提供方为所有的服务消费方都提供一套统一的 API,不搞特殊化。

比如支付上下文就集成了 微信支付上下文,微信支付提供服务的方式就是开放主机服务。

image-20240118222247131

可以用简写的 U 和 D 来表示这种上下游的关系。

在开放主机服务模式中,还隐藏了一种模式,因为开放主机服务的 API 很难为下游的某个上下文进行定制,所以下游的上下文就只能遵从它提供的模式,这个时候我们就称呼下游为 顺存者

顺从者

  • 没有模型到模型的转换

  • 一个上下文直接引用另一个上下文的部分模型

顺从者模式隐藏着一个风险,当你顺从一个上下文的时候,其实就是允许了它对你的侵入,如果我们除了对接微信支付,还需要对接支付宝等支付平台,就意味着需要引入多个上下文,这个时候如果不采用特殊方法,上下文就会变得比较混乱且难以维护。

image-20240118222943809

大泥球

在 DDD 中,这种比较混乱的模型就叫做大泥球。

  • 由混杂的模型构成的糟糕系统,模型不稳定且难以维护。这是一种反模式,我们要避免发生。
  • 与大泥球合作的上下文要确保自身不被污染,设置防腐层。比如集成旧系统,比如对旧系统进行重构的时候。

为了避免大泥球出现,就需要利用到另外一种很常见的模式 防腐层

防腐层

所谓防腐层,作用就是

  • 把上游上下文的模型转换成自己上下文的模型
  • 是由下游上下文实现的访问外部模型的一个代理层

image-20240118223343036

共享内核

在传统的 Java 应用架构里,有一种比较常见的做法,就是把一些比较重要的,比较内核的类放进一个 比如叫 core 的 Jar 包里,比如数据访问层,所有的服务都会引用这个包,或者去修改这个包,这种模式在 DDD 中叫做共享内核模式。

  • 两个上下文共享部分模型
  • 包括但不限于代码、jar 包、.so、数据库表等等
  • 慎用,仅当团队紧密合作且共享部分稳定;一旦涉及共享部分的变更,就会有比较大的风险。

合伙人

这种合作很紧密的团队,他们之间的关系称为合伙人,也是一种上下文映射的模式。

  • 技术无关,是一种团队协作关系
  • 两个团队之间可以随时互通有无,协同变更

客户/供应商

这是一种下游比较舒服的模式。

  • 下游上下文可以向上游上下文提需求
  • 一般用于核心域与非核心之间的协作

image-20240118224428316

比如 交易上下文和运营上下文都是核心域,设备上下文是非核心域,设备上下文可能会交给外包团队去实现,交易上下文和运营上下文都依赖它,它们都会向设备上下文提需求。

在日常开发中,客户/供应商模式是一种很常见的模式,它和 顺从者模式是一种反义词。

在顺从者模式中,下游上下文是弱势的一方,只能顺从上游,在客户/供应商模式中,下游是强势的一方。

tip

中台是相对低姿态的一方,因为中台的价值在于整合各个业务相对成熟和通用的部分,并且沉淀对业务有价值的通用组件,中台的价值一定要体现在业务上,这里的业务就是指下游的上下文,但是中台也有中台的难处,当中台要顺从多个上下文的时候,自己的上下文就容易变成大泥球。

如果要给多个上下文当供应商,也是一样,模型很难稳定下来。

中台的设计是很需要智慧和技巧的,否则很容易变成大泥球。

如果中台团队不给力,总是要让下游当顺从者,那么中台最后很可能会变得形同虚设,下游的上下文在被逼无奈的情况下可能会采用 分道扬镳 模式

分道扬镳

  • 两个上下文无协作,各自独立。
  • 当两个上下文之间的集成成本过高的情况下就会出现这样的情况。

image-20240118225333894

如果旧系统是一个大泥球,集成可能会非常困难,这时候新系统就可能会放弃集成,重新开始,最后流量逐步切换到新系统。

image-20240118225437019

公开语言

  • 标准化和协议化的模型
  • 所有的上下文都可以与公开语言中的模型进行双向转换
  • 对接了公开语言的上下文之间可以实现组件化对接
tip
  • 蓝牙协议、tcp/ip
  • Java 生态的 jdbc、jvm 标准等
  • SQL

SmartRM上下文映射

image-20240118225829639

这里对接的中台都是存在于客户的内部,而且不同客户的情况可能会有所区别,甚至有的客户内部的系统非常老旧,已经是大泥球了,比如很多 ERP 系统。所以很难要求客户为我们定制。

作为顺从者,我们就需要在自己这一层设置防腐层,保证自己模型的纯粹,不受污染。

小结

  • 上下文、团队之间的关系,重叠模型的映射关系。

  • 上下文映射模式(9种模式)、

​ 其中,开放主机服务是上游用的模式;防腐层是下游用的模式;顺从者和客户/供应商模式是两种相反的模式,在这两种模式种,下游分别扮演弱势和强势的角色;共享内核要慎用,除非团队是一种合作的模式,称之为合伙人;大泥球是一种反模式,不得已的情况下分道扬镳也是可以采用的模式;标准和协议中的模型,我们称之为公开语言,对接了公开语言,就可以把上下文组件化。