【问题标题】:Is it wrong if one Aggregate references other Aggregates Entity?如果一个聚合引用其他聚合实体是错误的吗?
【发布时间】:2021-12-13 09:55:12
【问题描述】:

例如,

public class Company:IAggregateRoot {
  public CompanyId Id;
  public ReadonlyCollection<Office> _offices;
  ...
}

public class EquipmentPiece {
  public EquipmentPieceId Id;
  private CompanyId _companyId;
  private OfficeId _officeId;
  ...
}

因此,当新的Office 被添加到Company 时需要检查逻辑,这是通过Company 聚合完成的(因为它取决于Company 上的其他属性)。 另一方面,每个EquipmentPiece 都必须引用安装它们的Office

我想避免将整棵树放在一个聚合中 (Company.Office.EquipmentPiece)。

这样做有什么概念上的错误吗?

【问题讨论】:

    标签: c# domain-driven-design


    【解决方案1】:

    正如 Evans 在 2003 年所描述的,聚合中的实体可以引用另一个聚合的 根实体

    在关系数据模型中,这通常看起来像有一个外键,当重新加载主(公司)时,它将用于查找第二个聚合根(办公室)。

    今天,我猜你更有可能看到第二个根的 id,而不是对根本身的引用:

    public class Company:IAggregateRoot {
      public CompanyId Id;
      public Collection<OfficeId> _offices;
      ...
    }
    

    【讨论】:

    • 是的,没关系。但Office 不是根实体,而是由Company 聚合管理的简单实体。问题是,另一个聚合 EquipmentPiece 是否应该引用 Office
    • 您应该只能通过聚合根和遍历来“访问”域实体。
    • 模式的好处来自于接受它的约束。
    • 您能否谈谈该“规则”/模式背后的原因是什么?
    【解决方案2】:

    你是对的,通过身份引用是相当普遍的事情。一些对象作为实体或值对象存在于特定聚合的边界内,并由另一个聚合中的标识引用。没有 DDD 警察会来骚扰你 :-)

    请考虑您可以写aCompany.Install(aPieceOfEquipment, atOfficeOfCompany) 之类的内容,以帮助确保您在已知的公司办公室安装设备(至少在您说的时候)。请考虑这与现实不符:要么您表达了在某个时间点将一件设备安装在办公室的意图您表达了这样一个事实,即一件设备安装在办公室。请考虑在安装设备之前,它仍然是尚未在任何办公室安装的设备。我并不是暗示您构建的模型需要考虑到这一点 - 选择最有用的模型就是工作。

    【讨论】:

    • 您的观察完全正确,事实上,我的模型确实考虑到了这一点……我刚刚在此处发布了简化版本,说明了特定的困境。但可以肯定的是,一件设备就是一件设备,安装与否。它的特点之一是它可以在特定时间安装到特定办公室。非常感谢您的想法!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多