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

Php DDD处理相互依赖的两个域模型之间的关联,php,domain-driven-design,Php,Domain Driven Design,跳入DDD的世界对我来说是一种旋风。虽然我做了很多研究,但我正在努力改变我的思维过程 所以,我有一个包和一个产品实体。没有产品,包装就无法发挥作用;反之亦然。当我需要获取属于某个包的产品时,问题就出现了(注意:该包是可定制的,这意味着属于该包的产品在下一轮可能会有所不同)。这似乎不属于任何实体,而且将其应用于包或产品实体将使它们紧密耦合 我必须强调,我之所以使用关联这个词,是因为我试图在域级别而不是在基础设施上解决这个问题 一点思考让我产生了以下想法: 使包成为聚合根&产品成为 包实体。然而,

跳入DDD的世界对我来说是一种旋风。虽然我做了很多研究,但我正在努力改变我的思维过程

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

我必须强调,我之所以使用关联这个词,是因为我试图在域级别而不是在基础设施上解决这个问题

一点思考让我产生了以下想法:

  • 使包成为聚合根&产品成为 包实体。然而,我相信这两种包装和产品 是否已唯一标识因其而产生的实体
  • 创建一个域服务,将包ID和映射带到 基础结构层以查找关联的产品。但是, 看一眼就觉得有点啰嗦
如果有人能让我恢复理智那就太好了!提前谢谢

普遍语言 DDD是关于语言的-这里的关键是听你的领域专家谈论产品和软件包-他们如何看待它们?以及与他们合作所涉及的流程

当他们创建一个软件包时,他们是否真的认为“我必须用这个软件包定义产品”,或者他们是否认为“我将设置一个软件包,然后将几个产品链接到它”——如果是后者,尽管乍一看可能觉得软件包离不开产品,请注意时间安排中的微妙含义——包可以在没有产品的情况下存在,因为他们希望将产品链接到它作为第二步

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

但是,如果存在业务规则,例如一个包只能有一个给定类型的产品,或者最多有5个产品,则将
PackageProduct
实体设置为
Package
聚合中的一个实体,聚合根为
Package
PackageProduct
将有一个对
Package
的引用和
ProductId
的属性。请参阅下面的一些术语说明

实体与聚合 根据你的问题,似乎对术语有一些混淆。在DDD中,我们有:

  • 实体:
    • 拥有一个比任何给定的财产都有效的身份
    • 具有可变状态
    • 一般来说,业务流程建模都是关于如何改变实体的状态
  • 聚合
    • 必须在其上强制执行不变量的一组实体
      • 不变量是必须始终保持不变的业务规则
    • 单个实体始终被指定为“聚合根”
    • 其他实体只能通过根引用聚合
    • 在对业务流程进行建模以改变状态时,聚合是所有实体的状态必须与不变量一致的边界
    • 在聚合边界之外,其他实体可能会得到异步更新-目标是
  • 域服务
    • 包含不属于单个实体的业务逻辑的服务
    • 它通常不仅仅是基础设施的包装
有关更多信息,请参阅

读与写操作 当我需要获得属于某个包装的产品时,问题就出现了

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

Ubiquitious语言 DDD是关于语言的-这里的关键是听你的领域专家谈论产品和软件包-他们如何看待它们?以及与他们合作所涉及的流程

当他们创建一个软件包时,他们是否真的认为“我必须用这个软件包定义产品”,或者他们是否认为“我将设置一个软件包,然后将几个产品链接到它”——如果是后者,尽管乍一看可能觉得软件包离不开产品,请注意时间安排中的微妙含义——包可以在没有产品的情况下存在,因为他们希望将产品链接到它作为第二步

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

但是,如果存在业务规则,例如一个包只能有一个给定类型的产品,或者最多有5个产品,则将
PackageProduct
实体设置为
Package
聚合中的一个实体,聚合根为
Package
PackageProduct