外部数据映射到域

时间:2017-06-27 09:32:06

标签: domain-driven-design

感觉就像我指的是上下文映射和反腐败层的DDD主题,但我不确定如何解决它。

如何从外部数据源构建/映射域对象?

作为示例,可能存在多个数据源(db,文件,外部服务)。由于我尝试构建尽可能类似于洋葱架构,这意味着我的域没有依赖关系。基础设施依赖于域(特别是基础设施实现域接口)

  1. 如果基础设施必须依赖于域(反之亦然),那是否意味着外部数据映射应该在存储库中完成?

  2. 如果通过构造函数创建对象被视为业务逻辑(除了域之外不应泄漏到任何地方),如何将外部数据映射到域对象?反射?其他方法?也许我误解了整个概念?

  3. 如果域对象创建需要来自多个源(服务,文件,数据库)的数据,是否意味着应用程序服务和基础架构(存储库)之间应该有一个单独的层来从多个存储库中提取数据,所有映射并返回结果域对象?

2 个答案:

答案 0 :(得分:1)

  

如何从外部数据源构建/映射域对象?

我知道有两种方法。

最常见的是应用程序通过对值的共同理解与域模型进行通信。应用程序采用它具有的表示(例如,文件中的字节),并从中构建域模型将理解的表示。您可能会通过工厂(了解如何将原始值转换为值类型)或构建器来完成此操作。

更罕见的方法是应用程序采用它具有的表示形式,并将其包装在域模型将识别的适配器中(而不是构建具体类型)。在这种风格中,值类型看起来更像是角色接口,使域模型不了解底层数据模型。

  

如果域对象创建需要来自多个源(服务,文件,数据库)的数据,是否意味着应用程序服务和基础架构(存储库)之间应该有一个单独的层从多个存储库中提取数据,是否所有映射并返回结果域对象?

我希望存储库能够自己完成这项工作 - 存储库的角色是键值存储的抽象。

Parnas wrote

  

我们建议从一个可能改变的困难设计决策或设计决策列表开始。然后,每个模块都被设计为隐藏其他模块的决定。

服务/文件/ db的选择是应该隐藏在模块(存储库)中的决策的一个示例,该模块的界面被选择为尽可能少地揭示其内部工作"。

答案 1 :(得分:0)

我更喜欢通过明确实施反腐败层来实现这一目标。我的域通常接受命令来执行任何操作,这是域模型可以接受的。这包括创建对象和执行状态转换。

ACL部分从外部数据源读取,或通过任何其他方式从它们接收数据。然后它将此数据转换为有效的域命令。所有预检查都是通过ACL完成的,ACL知道外部数据格式和域名。

有些情况下,一个外部事件会导致域中的多个操作,甚至多个有界上下文中的多个操作。通常这是通过使用流程管理器完成的。

可能就像您描述的那样,需要多个外部数据源来构建一个有效的域命令。在这种情况下,ACL就是这样做的,因为域中只有一个事务。如果外部资源也需要获得某种确认,它可能会变得更加复杂,流程管理器也可以用于此目的。