2. DDD聚合根思路,先去除不必要的关联依赖,找出高聚合,比如结合业务发现,A和B是代表各自聚合的实体根。切割后分别设计,聚合根实体对象的行为应该是保证对象内部状态一致性的那些动作。所谓逻辑一致性,也就是业务的规则 约束或校验,以日常例子说明,如果一群人的观点一致,那么我们就可以用XX组织 XX帮派来称呼他们,人以群分,物以类群,人或物因为有内部一致性才归类。
具体来说,类似状态模式,如果当前进入播放状态(假设有开始 播放 暂停 停止四个状态),那么下一个状态只可能是暂停或停止状态,肯定不是开始状态,那么这种一致性判断在什么时候什么地方判断呢?
很显然应该是在触发状态改变之前的动作行为中判断,那么这些动作就不能放在领域模型以外了,这也就是失血模型的根本问题所在。
除此保证内部一致性以外的动作方法可以不用放在领域模型内部,这些和业务场景有关的交互行为可以在服务中,也可以使用DCI将接口注入领域模型中,还可以用消息或事件实现。也就是说,用消息来实现交互,不管这种交互是由事件引起的,还是领域模型对技术架构发出的一种命令。
其实,聚合根也可以看成是一种角色,其职责是:维持聚合边界内状态的一致性(逻辑一致性)。
因此,聚合根与DCI可以结合,如下图:

在一个聚合设计中,我们可以考虑DCI,比如A实体是聚合根,也就是说,A已经固定扮演了聚合根这个角色,如果我们还希望A实现其他场景的角色职责?怎么办?
比如希望让A扮演持久化的角色,或者让A实现消息生产者的角色,这些职责虽然不是业务场景职责,毕竟A是生活在计算机世界中,也要遵守计算机领域场景的一些规则游戏。
使用Mixin/AOP实现的动态组合太多角色可能破坏A实体充当聚合根这个主要角色,在这种情况下,以DCI名义只引入一个事件发送者角色,让A实体主要实施聚合根职责,其他以外的职责全部通过以事件消息的形式委托其他类来实现。
以http://www.jdon.com/45318案例为说明如下,BacklogItem假设等同与聚合根A, product相当聚合根B, A和B的依赖交互可用消息事件实现:
public class BacklogItem{
//ProductVO是另外一个聚合根实体Product的值对象
private ProductVO productVO;
@Inject //DCI的角色注入句柄 组入(织入)一个领域事件发送者角色
private DomaineventsRole domaineventsRole;
//需要交互的方法
public void updateProduct(){
//向Product聚合根发事件消息实现交互操作
domaineventsRole.send(new ProductUpdatedEvent(productVO.getProductId));
}
//开始记录方法会改变自身内部状态,直接作为基本方法。
public void startLog(){
..
}
}
<p>
|
[该贴被banq于2013-04-23 08:28修改过]
[该贴被banq于2013-04-23 09:43修改过]