请教banq DDD聚合问题

在JiveJdon3的Forum,ForumThread,ForumMessage关联中哪个是聚合的根?在多个对象关联的情况下如何分辨出哪个是聚合的根?

Forum是聚合根。但因为ForumMessage非常重要,其中包含很多复杂元素,针对这些元素ForumMessage则是聚合的根。

聚合的根不是从关联中识别,因为只有识别出聚合的根,才设计出聚合等关联关系,不能从结果中寻找原因。

聚合的根是从需求中获得,那些我们关注的最主要的对象有可能就是一个包含很多聚合关系的根或者说总容器所在。这个也需要摸索和反复比较,聚合根找到,系统主要模型就确定,这是很关键一步。

[该贴被banq于2007年08月21日 13:36修改过]

>Forum是聚合根。但因为ForumMessage非常重要,其中包含很多复杂元素,针对这些元素ForumMessage则是聚合的根。

是不是说在Forum,ForumThread,ForumMessage中可以按需求的不同角度建立出不同的聚合和该聚合的根?

>聚合的根不是从关联中识别,因为只有识别出聚合的根,才设计出聚合等关联关系,不能从结果中寻找原因。

如果按结果来讲Forum,ForumState组成一个聚合,Forum是根。
ForumMessage,Fourm,ForumThread组成一个聚合,ForumMessage是聚合根。
ForumMessage,Fourm,ForumThread,ForumThreadState组成一个聚合,ForumThread是聚合根。
这样子对吗?

DDD说聚合看作一个整体,外部对象只能引用聚合的根,如果删除聚合的根,所有的子项都会被删除。那么ForumMessage删除的话,FourmThread和Forum都会被删除,这样的逻辑好像不大对吧?


有些乱套了,重新整理思路如下:

首先我们必须区分关联和聚合区别。

Forum ForumThread和ForumMessage中, Forum和后两者是一般关联关系,而非聚合关系,因为一个论坛可以没有任何主题或帖子,空白论坛也是可以存在的。当然严格来说,没有内容的论坛是否称得上论坛?所以,前面我把Forum和后两者看成聚合关系了,如果是,那么Forum就是聚合的根了。

ForumThread和ForumMessage是聚合关系,一个主题系列必然包含一个ForumMessage。

当然ForumMessage对于其内部如ForumMessageState等都是聚合的根。

总之,必须先找出聚合来,再找出聚合的根。


[该贴被banq于2007年08月21日 13:41修改过]

>首先我们必须区分关联和聚合区别。
Evans DDD的聚合和传统UML中的聚合的概念可能有些不同,Evans DDD书中写道:“一个聚合是一簇相关联的对象,出于数据变化的目的,我们将这些对象视为一个单元。”这个就是说聚合是一个范围,可能是多个对象之间的关系而不是两个对象之间的传统聚合的关系。

而banq所说的聚合是两个对象之间很强的整体和部分关系,您说的和Evans DDD所说的有所差别。

我把Evans DDD定义的聚合称为主观聚合,这就象一个树形结构,任何一个节点下面都有子节点,那么这个节点就是子节点的根,取决于你关注范围。

不过话说回来了,我不认为Evans 定义的聚合和我们通常说的聚合有太大差别,因为这是最基本的对象关系,之所以我们觉得不同,还是和翻译等语言表达有关。
[该贴被banq于2007年08月21日 16:39修改过]

多谢banq
>当然ForumMessage对于其内部如ForumMessageState等都是聚合的根。

ForumMessage为根的聚合范围中具体对象除了ForumMessageState还有哪些?

在JiveJdon3的聚合中有没有对不变量的保证? 具体是什么呢?

ForumMessage中其实没有FormMessageState,我举的一个例子,真正有uploadFiles和Properties等子对象,uploadFiles为一个帖子的附件,删除一个帖子必须删除其所有的uploadFiles,我们通过将uploadFiles聚合进入ForumMessage,那么外部访问uploadFiles,必须通过ForumMessage,这就保持一致性,这也是使用对象的好处。

如果不使用对象聚合,使用数据库,那么数据库对于所有程序都是透明的,一个程序员想使用uploadFiles时,它就直接去访问uploadFiles所在数据库,并进入更动,这就绕过了uploadFiles的聚合根也就是所有者ForumMessage,破坏一个实体的内部一致性,是非常可怕的,而且是不符合逻辑的,现实中,我们都不可能绕过一个对象,直接对其内部进行访问,而是首先必须访问这个对象或物体。

Forum和ForumState也是聚合关系,ForumState表示论坛状态,包括最后一个回帖等,当有新贴发表时,我们必须及时保证ForumState更新,但这种更新没有必要对Forum整个对象更新,而是局部,局部更新也必须经过Forum对象,这些都是不变量的保证。

如果是这样的话,把ForumMessage做为聚合根,ForumMessage其中的ForumThread和Forum都不是聚合根的子项了? 这两个是不是Evans DDD所说的多余关联呢?

>ForumMessage其中的ForumThread和Forum都不是聚合根的子项,Evans DDD所说的多余关联呢?

ForumMessage引用了ForumThread和Forum不属于模型设计上考虑范畴,属于双向关联,主要是为技术实现提供方便(如Hibernate等持久化),并不是一个对象中引用另外一个对象一定是聚合,两者不是相等关系,所以不能单从关联关系这个结果来推原因。

这么说来一般的聚合根和子项关系都是1:N、1:1这种了?

聚合是关联的一种,关联关系有1:N 1:1等单向或双向关系。这些基本对象关系需要牢牢掌握。

OK,懂了,非常感谢banq的回复!

收藏

收藏+每日拜读!