不明白书上,一个对象聚合在2个对象下面是怎么回事

12-09-24 testoktest
书上133页 图7-8

leg聚合在itinerary

还聚合在transport schedule

那leg是实体还是值对象?它属于哪个聚合根下呢?生命周期是怎么样的呢?

看书上,itinerary是路线预定和实际运输的结合点,并且itinerary已经聚合在cargo下面了

那它下属的聚合leg也应该在cargo下面了

那又聚合在transport schedule下面又算是怎么回事呢,它们三者之间是如何调用的呢?

[该贴被admin于2012-09-25 08:36修改过]


clonalman
2012-09-24 22:25
楼主犯了几个错误:

2012-09-24 18:23 "@testoktest"的内容
书上133页 图7-8 ...

1、问问题的时候应该完整一点,至少应该指出是哪一本书,中文版还是英文版的(这本书被翻了不下50遍了)

2012-09-24 18:23 "@testoktest"的内容
leg聚合在itinerary

还聚合在transport schedule

那leg是实体还是值对象? ...

2、leg聚合在这两个对象下,只是说明leg与itinerary、transport schedule的关系,不能因为它聚合在多个对象(实体或值对象)下,就说明它是实体或值对象;实体或值对象与否,只能是这个对象在业务中来判断,简单的理解是这个对象在业务中是否有惟一标识

2012-09-24 18:23 "@testoktest"的内容
它属于哪个聚合根下呢?生命周期是怎么样的

3、楼主混淆了UML的聚合与DDD聚合根的概念。

路程(leg)生命周期取决与业务,这个例子中一个线路(Router)可以有多段路程(leg),不同的线路(Router)也可能有相同的一段路程(leg),所以他应该要有独立生命周期,但是这个生命周期受后续的“运输计划”或“货物运输”的约束。

2012-09-24 18:23 "@testoktest"的内容
它属于哪个聚看书上,itinerary是路线预定和实际运输的结合点,并且itinerary已经聚合在cargo下面了

那它下属的聚合leg也应该在cargo下面了

那又聚合在transport schedule下面又算是怎么回事呢,它们三者之间是如何调用的呢?

4、这个必须从模型所表达的业务含义来理解。

货物出运(Shipping)模块的业务模型表达的含义是“规划线路->运输计划->货物运输(最多一个旅程)”

(建议Admin编辑一下,把UML图加上去就好看一点)

[该贴被clonalman于2012-09-24 22:43修改过]

testoktest
2012-09-25 01:25
图片不知道怎么加,说登陆后才能加,虽然我登陆了

是中文版的,清华大学出版社的

我明白了,leg是个实体,也是个聚合根

itinerary也聚合了leg,这是不是就是聚合根说过的:聚合内的对象,可以持有其他聚合根的引用?

我不懂的是这个引用是怎么导航的?

是否就是itinerary从仓储中载入的时候,将leg聚合根也加载到itinerary内部?不管是否懒加载

我看了http://www.jdon.com/43276 bang大说的

通过场景来交互

是不是说,itinerary需要列导航到leg聚合根时,会触发领域消息,消息总线接收后,从leg仓储中取出leg聚合根,然后派发给itinerary?

除此之外,还有别的方法完成 聚合根之间的导航吗?

clonalman
2012-09-25 07:42
2012-09-25 01:25 "@testoktest"的内容
聚合内的对象,可以持有其他聚合根的引用? ...

主要是看业务需求,一个聚合根完全可以导航到另一个聚合根完全,它说明两个聚合根之间关系比较密切,如果关系比较松散,使用数据引用即可。

业务建模:CQRS应用场景

出货单与销售订单、采购退货单就是一个松散的关系,业务上出库单是仓库人员的作业属库存模块,销售订单是销售人员的作业属销售模块,采购退货单由采购人员发起,属于采购模块;出货单只要持有销售订单单号、采购退货单单号即可,没有必要进行导航

象销售订单与客户的关系就是典型聚合根与聚合跟之间的导航关系,使用领域事件来处理,纯粹是自己给自己找麻烦。

2012-09-25 01:25 "@testoktest"的内容
我看了http://www.jdon.com/43276 bang大说的

通过场景来交互是不是说,itinerary需要列导航到leg聚合根时,会触发领域消息,消息总线接收后,从leg仓储中取出leg聚合根,然后派发给itinerary?

bang讲的DCI与DDD的分析方法,其实是不同的思维方式(个人建议banq不要把他们硬是拉到一起,很容易造成一些人困惑),领域事件解决领域之间相互依赖与调用的问题,最好放在相互依赖的模块之间使用,在聚合根之间粒度太小(当然发出事件可以在实体或服务之中)。

[该贴被clonalman于2012-09-25 07:55修改过]

[该贴被admin于2012-09-25 08:35修改过]

clonalman
2012-09-25 07:50
2012-09-24 22:25 "@clonalman"的内容
不同的线路(Router)也可能有相同的一段路程(leg) ...

纠正一下,这是错误的,翻了一下书本,leg可以导航的Router的.

banq
2012-09-25 08:54
2012-09-25 01:25 "@testoktest"的内容
我不懂的是这个引用是怎么导航的?

是否就是itinerary从仓储中载入的时候,将leg聚合根也加载到itinerary内部?不管是否懒加载 ...

是的,leg路程是itinerary行程的组成部分。一般同时加载,因为这是其重要内容,就像帖子内容是帖子的重要组成部分一样。

如果你要使用场景交互的懒加载也是可以,我个人一般建议核心部分还是实时加载好,除非有性能上考虑。

itinerary属于Route Specification的一个实现,itinerary本身属于规格模式的实现,至于Transport和leg的关系,我觉得类似商品目录和商品之间的关系。

楼主能够从导航这个角度来研究对象之间关系是很好的,说明OO上升到一定水平,有时从导航角度看看,可以检查我们的模型图是否能落地实现用例功能,但是不能和领域核心冲突,尽量少用双向导航,对于一些模型图不能完成的导航,可以直接使用Repository来替代。

至于具体如何导航,clonalman建议也不错,如果很松散,使用数据ID进行表达,这时基于领域事件的懒加载也许能够派上大用处。

猜你喜欢