DDD。何时在树状结构中使用聚合根?

时间:2019-04-28 10:56:56

标签: domain-driven-design aggregateroot

在有界上下文中,我创建了一个Entity,它是该上下文中其他对象的集合。问题是,Entity的一个实例可能与另一个Entity处于子代关系。对于数据库而言,这意味着存在一个parent_id字段,该字段引用了同一entities表中的一行。

从DDD的角度来看,问题是可以使Entity的实例成为其自己的构造函数的参数吗?或者最好使用聚合根(或Entity标识符)。因此,哪种方法更好:

class Entity {
     public constructor (arg1, arg2, Entity parent) {
         ...
         this.setParent(parent);
     }
}

或这种方式:

 class Entity {
     public constructor (arg1, arg2, int parent_id) {
         ...
         this.setParentId(parent_id);
     }
 }

1 个答案:

答案 0 :(得分:2)

仅仅因为您具有树状结构,并不意味着该结构中的所有实体都应属于同一 Aggregate 的一部分。

您可以将系统设计为在其自己的集合中具有每个 Entity实例。由于每个实体都有一个父级,因此您必须引用

  • 执行此操作的一种方法是像第一个示例一样具有对象引用

  • 另一种方法是像第二个示例一样使用按身份引用

如果使用对象引用,则意味着必须从数据库中一起加载所有引用的对象。这可能会导致您加载大量它们。如果您的应用程序不需要这样做,则最好避免。

如果您选择使用对象引用,则可以像在营地中一样将实体传递给构造函数。

如果使用 ID参考,则只能加载一个对象,然后,如果需要,可以使用ID加载另一个对象。如果您希望有多个聚合,这些聚合仅在特定情况下彼此需要,并且您不需要一直将它们一起加载,因为您的应用程序不需要这样做,那么这很有用。

这是一个例子:

public TreeNode {
  public Guid ParentID { get; private set; }
}

public void DoSomethingToNode(Guid nodeId) {

  var node = TreeNodeRepository.GetById(nodeId);
  var parent = TreeNodeRepository.GetById(node.ParentID);

  // do stuff with parent and child.
}

如果您还没有读过DDD book,我推荐您。

This essay from Vaughn Vernon在聚合模型建模方面也很出色