在以前的《基于领域分析设计的架构规范-领域分析基础》一文中,我有介绍过关于聚合的概念,其中聚合中非根实体的判别,是依照其不能离开聚合根而单独存在,好比订单明细不能离开订单而存在,因此订单明细只属于订单聚合中的一个非根实体。java
但我一直以为还过于抽象,应该还有更严谨完善的判断方式。 因此,本文就一块儿来思考个案例:架构
在一个资讯平台上,用户能登录后发表文章,并阅读文章。因此,在一开始,二者的关系是这样的: .net
以后,来了一个新需求,说用户可以对文章发表评论,那么,评论这个实体,该如何设置呢?咱们不妨思考一下:设计
若是按我以前文章中提到的,颇有可能就会陷入上面的思考了,颇有可能会认为评论应该是“文章的评论”,因此评论应该是隶属于文章聚合的。日志
但怎么看都以为别扭啊!很是别扭!但按以前的规则来讲,应该是这么回事呀,问题出在哪呢?code
咱们来思考:评论是如何建立的?产品流程以下:blog
用户在文章下方的评论框中输入评论,点击提交生命周期
那么代码上顺利成章应该就是这样:get
Comment comment = commentFactory.create(newCommentRequest);
但若是要强行用文章聚合的设计方案,就会很是别扭了:产品
//既然聚合根是文章,那么确定要先找到文章,再给文章加入评论 Blog blog = blogRepository.getById(newCommentRequest.getBlogId()); blog.addComment(newCommentRequest);
固然,“别扭”一词还不够严谨,换用一个更严谨的说法:
评论虽然与文章有关,但其建立过程并非发生在文章的各项生命周期的操做中的,而是独立建立的,因此,它应该是一个新的独立的聚合
具体说来:文章有建立,编辑,审核,删除等等操做流程,但这个过程当中,并不会产生评论,意味着,评论并非文章生命周期中的直接衍生物,它虽然关联了文章,也关联了用户,但倒是独立被建立,也有本身独立的生命周期(能被单独修改,单独删除)。
因此,关系图应该是
而相比之下,咱们再看更常见的非根实体,好比用户登录日志,订单变动日志,这些实体,其建立的过程,都是在用户登录,订单各项操做的过程当中被建立出来的,生命周期的一开始就和根实体强绑定。
因此,此次,我总结了如下几个原则,来判断一个实体,是否应该做为一个新的领域聚合的根存在,判断的优先程度由高到低是:
其中,(2)(3)只是做为一个辅助参考,最关键的仍是(1),若是(1)能遵照了,十之八九能够定义为一个独立的聚合了。