领域驱动设计如何连接两个上下文?

问题描述

如何将一个有界上下文与另一个有界上下文联系起来?

例如我有一个购物车上下文和产品上下文,当我首先将产品添加到购物车时,我想检查产品是否甚至存在所以我的问题是你如何在单体项目中连接上下文?

免责声明
我知道在微服务架构中,您可以请求某些 API 端点来恢复您需要的确切对象并将其映射到值对象。但是在单体应用中该怎么做呢?创建一个桥接类或创建一个数据库存储库,它将从数据库的某个表中检索值对象?

我期待着您的想法,感谢您的帮助。

解决方法

至少有 2 种不同的方法来管理这个。

上下文之间的数据克隆

在此解决方案中,您为每个上下文使用多个相似的表,其中数据在每个上下文之间部分复制。

因此,为了支持您的请求,您必须在用于购物车的上下文中维护一份产品数据的副本。 为了支持这一点,您可以使用:

  1. 使用事件处理程序,每次产品上下文发生变化时,您都会更新购物车上下文
  2. 将信息从一个上下文克隆到另一个上下文的定时作业
  3. 两者的结合
  4. 其他解决方案...

无论如何,无论您选择什么,最重要的是您必须接受最终一致性的概念:您总是使用陈旧数据(也许只有几秒钟,但它无论如何都是陈旧的),因此您必须管理由此可能出现的问题。例如,如果购物车上下文中的产品包含仓库中不再存在的商品,您会怎么做?

您可以(必须...)在每个上下文的基础架构层中实现此支持代码,因此您可以让所有其他层不知道他们管理的数据发生了什么。最后,这个解决方案类似于拥有一堆微服务,只是一切都构建在一个大项目中。

注意:这将是纯粹的解决方案,每个有界上下文彼此分离,即使它们都在一个项目中构建在一起。

在多个上下文中重用持久对象(数据库表)

我在写任何东西之前就先动手:这个解决方案是可能的,但前提是你真的对你项目的每个方面都有很好的控制。有些人会尖叫这是一种失常,另一些人会说在现实世界中你必须始终接受妥协。

通过这个序言,我解释了我的意思:与其在使用数据的每个上下文中都有几个(几乎)表的克隆,而是用(很多,也许)代码来支持这一点,原始表是直接用于多种情况。因此,只要您需要 Cart 上下文 中的 产品,而您仍然使用来自该上下文的 产品存储库 的实现来访问它(购物车上下文),实际上你总是从同一个表中获取数据。

这有其自身的缺点:可能是上下文需要额外的数据,因此应该扩展表(有人会说被污染),并带有额外的字段;表中的每个更改都可能需要检查使用它的代码,因为该表是共享的。

但是,许多应该编写来管理克隆的额外代码消失了。而且,我的意见,在受控环境中,与第一个解决方案所需的额外工作相比,对于单体项目,无论如何将代码构建在一起,这是一个很大的优势。而且,当访问表的代码经过深度测试(没有测试,没有增益)时,一些问题也更容易管理。


注意(个人经验):我使用第二种解决方案。我们有一个很大的单体,有很多表,在几个上下文之间共享数据。为每个上下文克隆数据的过程是不可行的:为此花费了太多时间,而没有考虑所有后备情况。共享表要快得多,并且可以开发良好的拆分有界上下文。我不使用 JPA (Java ORM),所以我控制加载域实体的 SQL 代码。有关持久性访问的所有内容都经过测试,因此每当发生变化时,我都会立即收到报告。