域驱动设计 - 与父实体有关的实体的子命令

时间:2013-09-13 09:16:56

标签: domain-driven-design entity-relationship aggregate invariants

我有两个聚合父母和孩子,比方说。父母可以有很多孩子(孩子)。 一个孩子只能属于一个父母。

我需要跟踪子实体的排序顺序,以便当您获得父级的子实体时,列表按此顺序排列。

明显的数据库架构如下:

enter image description here

但是,模型的不变量需要是明确定义此顺序。 因此,如果你在Child上有一个方法,Child.SetOrdinal(int)说,那么这个不变量就不受保护了(没有什么可以阻止你将两个Childs设置为序数3)。 我不想将它们全部集中到一个大的聚合中。

我看到的替代方案是如下数据库: enter image description here

我已经引入了一个链接表来存储关系和顺序,这将在Parent聚合中,其中可以保护不变量。但这确实增加了数据库的复杂性。

还有另一种方式,还是第一种更简单的版本还不错?

1 个答案:

答案 0 :(得分:0)

采用第一种方法时,您的模型可能看起来像这样(假设父和子是AggregateRoot):

public Class Parent {
    private Long id;
}

public Class Child {
    private Long id;
    private Long parentId; // most orm need this field.
}

然后,您可以使用childRepository.findBy(parentId): List<Child>检索属于父级的所有子级,并使用parentRepository.findBy(child.getParentId()):Parent检索子级的父级。但这不是你的情况,因为你说“然而,模型的不变量需要是这个顺序是明确定义的”。这导致了另一种方法:Parent和Child as AggregateRoot和ValueObject来保持关系:

public Class Parent {
    private Long id;
    private List<LineChild> children;
}

public class LineChild {
    private int ordinal;
    private Long childId;
}

public Class Child {
    private Long id;
}

但是在我的过期中,大多数orm不支持​​这个(使用第二个db模式)。一些“半工具”可以提供帮助,比如iBATIS。

<resultMap class="Parent">
    <property name="id" column="id" />
    <property name="children" column="id" select="findChilren"/>
</resultMap>

<select id="findChilren" parameterClass="long" resultMap="LineChild">
    select * from Child where parant_id = #parantId# order by ordinal
</select>

<resultMap id="LineChild" class="LineChild">
    <property name="ordinal" column="ordinal" />
    <property name="childId" column="id"/>
</resultMap>

但是你失去了orm框架的所有好处,比如动态更新等等。

或者,考虑最终的一致性?

最后但很困惑,为什么“一个孩子只能属于一个父母”?我有妈妈和爸爸! :P