我在纠结于聚合体和聚合根。我有一个自然的聚合根,它可以为大约60%的用户请求工作。也就是说,这些请求自然适用于总根。
在我的聚合中,我有另一个实体,它只能作为聚合根的成员存在。然而,用户将被告知这个其他实体对象。在概念上,用户直接操作这个非聚合根对象有时是有意义的。
所以,我想我有几个选择:
。
请注意,顶级聚合根将保存该其他实体的集合。
示例:
主集料根: Car
第二个实体:座椅(汽车有两个或四个座位取决于类型)。在我的领域,座位只能作为汽车的一部分存在。
该领域中的大多数操作都在汽车级别。因此,这将是一个很好的候选聚合根。然而,(我在这里为例子而挣扎),一些操作将位于座位级别,例如SpillCoffee、ChangeFabric、Clean...l。
座椅和汽车都会是集团化的根源吗?还是我应该总是从汽车开始?
谢谢
发布于 2009-06-10 17:02:55
聚合的思想是保证一致性,它是负责数据完整性和强制不变量的根。
假设有这样一条规则:“所有座位的结构必须相同”,或者“只有在车内有人的时候,你才能把咖啡洒在座位上”。一旦客户能够单独改变结构,或者这些不变式需要被强迫到外面(危险区),执行起来就会困难得多。
IMHO,如果完整性或强制不变量不是问题,那么聚合并不是真正需要的。但是,如果有必要的话,我的建议是一切都从汽车开始。但要经常想到模型。如果有这样的不变量,那么是谁强制这些不变量的?然后尝试将这个想法传递给代码,一切都会好起来的。
发布于 2009-06-12 18:24:06
您可能需要对域模型的某些方面有更深入的了解。这个问题表明,您将要发明一种组织实体来提供系统的方法,而理想情况下,在实现之前已经回答了这类问题。
当这种情况只出现在系统实现上时,无论是回过头来检查域还是发现了一些脆弱性,其反馈可能--而且应该--对业务的相关细节进行汇总,以使该领域更丰富并更好地建模。
在car示例中,我使用了两个关联不同上下文的聚合体的方法。第一种是“汽车有座位”的办法,在这个总数中,“座椅”可能采取的行动只是那些有意义的“作为汽车一部分的座位”。例如:干净。
第二个总数将是在“席位”的范围内,并将有可能采取的行动和作为一个单独席位的配置。例子: ChangeFabric,ColorList。这样,聚合的“汽车”就有了“座位”,但是客户可以知道在有意义的上下文中的座位。这是危险的,就像上一篇文章中说的。如果上下文之间的修改影响域完整性,则丢失所有聚合概念。
发布于 2009-06-10 17:06:48
对于带有购物车和行项的购物车,我将两者作为聚合根,因为我经常独立地修改它们。
public class Cart : IAggregateRoot
{
public List<LineItem> LineItems {get;}
}
public class LineItems : IAggregateRoot
{
public List<LineItem> LineItems {get;}
}但是,对于orders,我有一个单独的有界上下文,在这种情况下,我只需要一个聚合根,因为我不再需要独立地修改行项。
public class Order : IAggregateRoot
{
public List<LineItem> LineItems {get;}
}另一种方法是从子ID中查找聚合根。
Car GetCarFromSeatID(guid seatID)https://stackoverflow.com/questions/976564
复制相似问题