具有 DDD 和遗留数据的模块化单体

Modular Monolith with DDD and Legacy data

在我的域中,我有以下模块:

WMS(仓库管理) 销售订单(包含销售订单行等。) 这是一个多租户应用程序,这意味着数据库包含许多公司,每个公司都有自己的一组数据。有很多杂物,但也有很大一部分是可操作的。

一些数据来自遗留系统,您将如何在此处进行集成?将有一个集成 运行 一个时间间隔并将数据发送到 API,向上和向下写入(保持同步)。所以基本上我问的是如何将现有数据导入系统,这个问题不应该是分布式事务吗?也可能有来自其他系统的数据导入。数据需要保持同步的原因是因为遗产必须存在更长时间。

编辑:

Let's say both modules stores it's own version of product:

WMS.Product:
- ProductName
- ProductNumber
- QuantityInStock

SalesOrder.Product:
- ProductName
- ProductNumber
- RetailPrice

Should the integration command look like:

Integration.Commands.SaveProduct
- ProductName
- ProductNumber
- RetailPrice
- QuantityInStock

And shouldn't this transaction be distributed across the different modules?  If the transaction goes both ways there will have to be some kind of link between ids..

当集成必须双向进行时,如何使用上帝模型从遗留系统实施反腐败层..

提前致谢。

这是我的建议:

你会如何在这里进行整合?

您可以像集成域的任何其他外部部分(例如数据库)一样进行集成。创建一个“连接器”,其唯一的工作就是与该系统交互并将您的域转换为该系统和 vice-versa。您的域可以接触到的一个“接口”将掩盖交互的细节,并在基础设施层上实现。

我问的是如何将已有的数据导入系统...可能还有其他系统的数据导入

如果您有一组类似的从系统导入和导出数据的步骤,您可以创建一个接口并创建一个连接器来为所有数据导入实现该接口。

总而言之,将其视为外部系统(因为它是),并像处理数据库一样通过基础设施层 read/write 处理它。

编辑: 根据您的修改

更清洁的方法

您需要 2 个不同的命令。一个更新仓库,另一个更新销售订单。

因此,您将拥有 Integration.Commands.PulledProduct 和 Integration.Commands.OrderProduct,而不是 Integration.Commands.SaveProduct。当您销售产品时,您的域本身可以触发由 WareHouseManager 模块处理的“拉取产品”事件。您的外部触发器必须能够区分命令。 如果采用这种方法,您会发现集成几乎变得“合乎逻辑”。

一种思考方式是使用无处不在的语言。中小企业可能将您的系统描述为“用户输入销售订单(事件 1),然后我们从仓库中提取请求的数量(事件 2)”。因此,这两个事件在您的域中必须是可区分的。如果我仍然不清楚图片,请告诉我。