在有界上下文中,我创建了一个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);
}
}
答案 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在聚合模型建模方面也很出色