DDD处理两个相互依赖的域模型之间的关联

时间:2016-09-09 10:03:24

标签: php domain-driven-design

潜入DDD世界对我来说是一种旋风。在我做了大量研究的同时,我正在努力改变我的思维过程。

所以,我有一个包和一个产品实体。如果没有产品,包装就无法运作;反之亦然。当我需要获得属于包的产品时,问题就出现了(注意:包是可自定义的,这意味着属于包的产品在下一轮可能会有所不同)。看起来这既不属于任何实体,而且将其应用于包或产品实体会使它们紧密耦合。

我必须强调我使用关联这个词,因为我试图在域级而不是基础架构上解决这个问题。

一点点思考让我想到了以下几点:

  • 使包成为聚合根&产品是兄弟姐妹的 包实体。但是我相信这两个包装和包装制品 由于它们的实体是唯一标识的。
  • 创建一个域名服务,该服务将包含ID&映射到 基础架构层,以查找关联的产品。但是,这个 看起来很长一段时间才能卷起来。

如果有人能让我再次理智,那就太好了!提前谢谢!

2 个答案:

答案 0 :(得分:2)

无处不在的语言

DDD完全与语言有关 - 这里的关键是听你的领域专家谈论产品和包装 - 他们如何看待它们?关于与他们合作的过程?

当他们创建一个包时,他们是否真的认为“我必须用这个包定义产品”,或者他们认为“我会设置一个包,然后将一些产品链接到它” - 如果后者虽然它可能在第一次脸红时觉得没有产品就不能存在包装,但要注意时间上的微妙含义 - 包装可以在没有产品的情况下存在,因为它们期望将产品链接到它第二步。

鉴于此,您可以将链接建模为完全独立的聚合,并将单个实体作为根,例如PackageProduct(或者更好的是,您的域专家用来定义关联的一些术语),并在产品链接到包时简单地创建此聚合的新实例。该实体上有一个PackageId和一个ProductId。

但是,如果有业务规则,例如一个包只能有一个给定类型的产品,或者最多只有5个产品,然后使PackageProduct实体成为Package聚合中的实体,其中Package为聚合根。 PackageProduct会引用PackageProductId的属性。请参阅下面的一些术语说明。

实体与聚合

根据您的问题,似乎可能会对术语产生一些混淆。在DDD中,我们有:

  • 实体:
    • 拥有超出任何特定财产的身份
    • 有可变状态
    • 通常,建模业务流程就是要弄清楚如何改变实体的状态
  • 汇总
    • 必须强制执行不变量的一组实体
      • 不变量是必须始终保持的业务规则
    • 始终将单个实体提名为“聚合根”
    • 其他实体只能通过根
    • 引用聚合
    • 在对业务流程进行建模以改变状态时,聚合是所有实体的状态必须与不变量一致的边界。
    • 在聚合边界之外,其他实体可能会异步更新 - 针对eventual consistency
  • 域名服务
    • 包含不属于单个实体的业务逻辑的服务
    • 它通常不仅仅是一个基础架构的包装器

有关详细信息,请参阅https://lostechies.com/jimmybogard/2008/05/21/entities-value-objects-aggregates-and-roots/

读取与写入操作

  

当我需要获得属于软件包的产品

时,会出现问题

这听起来很像是为了支持用户界面或报告?在这种情况下 - 不要强调实体模型。实体模型用于确保在用户尝试修改系统状态时保持业务规则。执行读取操作时,无需修改状态,因此可以绕过模型。定义将数据存储投影到DTO上的查询,并定制投影以满足UI或报告的需要。

答案 1 :(得分:0)

  

当我需要获得属于某个软件包的产品时,会出现问题(注意:软件包是可自定义的,这意味着属于软件包的产品在下一轮可能会有所不同)。

这听起来像是一个查询。它通常有助于分离命令(可以改变域模型的东西)和查询的建模。