DDD中聚合划分的思考

在以前的《基于领域分析设计的架构规范-领域分析基础》一文中,我有介绍过关于聚合的概念,其中聚合中非根实体的判别,是依照其不能离开聚合根而单独存在,好比订单明细不能离开订单而存在,因此订单明细只属于订单聚合中的一个非根实体。java

但我一直以为还过于抽象,应该还有更严谨完善的判断方式。 因此,本文就一块儿来思考个案例:架构

案例背景

在一个资讯平台上,用户能登录后发表文章,并阅读文章。因此,在一开始,二者的关系是这样的: 资讯平台关系图1.net

以后,来了一个新需求,说用户可以对文章发表评论,那么,评论这个实体,该如何设置呢?咱们不妨思考一下:设计

  • 评论必然是归属给一个文章的,至少目前需求来看是这样,因此评论离不开文章
  • 评论必然也是一个用户发起的,评论也离不开用户
  • 看起来有点棘手...不过总之评论确定不能独立存在了。

若是按我以前文章中提到的,颇有可能就会陷入上面的思考了,颇有可能会认为评论应该是“文章的评论”,因此评论应该是隶属于文章聚合的。日志

设计分析

但怎么看都以为别扭啊!很是别扭!但按以前的规则来讲,应该是这么回事呀,问题出在哪呢?code

咱们来思考:评论是如何建立的?产品流程以下:blog

用户在文章下方的评论框中输入评论,点击提交生命周期

那么代码上顺利成章应该就是这样:get

Comment comment = commentFactory.create(newCommentRequest);

但若是要强行用文章聚合的设计方案,就会很是别扭了:产品

//既然聚合根是文章,那么确定要先找到文章,再给文章加入评论
   Blog blog = blogRepository.getById(newCommentRequest.getBlogId());
   blog.addComment(newCommentRequest);

固然,“别扭”一词还不够严谨,换用一个更严谨的说法:

评论虽然与文章有关,但其建立过程并非发生在文章的各项生命周期的操做中的,而是独立建立的,因此,它应该是一个新的独立的聚合

具体说来:文章有建立,编辑,审核,删除等等操做流程,但这个过程当中,并不会产生评论,意味着,评论并非文章生命周期中的直接衍生物,它虽然关联了文章,也关联了用户,但倒是独立被建立,也有本身独立的生命周期(能被单独修改,单独删除)。

因此,关系图应该是

资讯平台关系图2

而相比之下,咱们再看更常见的非根实体,好比用户登录日志订单变动日志,这些实体,其建立的过程,都是在用户登录,订单各项操做的过程当中被建立出来的,生命周期的一开始就和根实体强绑定。

因此,此次,我总结了如下几个原则,来判断一个实体,是否应该做为一个新的领域聚合的根存在,判断的优先程度由高到低是:

  1. 该实体的建立过程是不是彻底独立的,而非依赖与其余某个实体的命令操做;
  2. 该实体是否能被单独进行删/该操做,而非好比伴随其余某个实体的命令操做而变更;
  3. 该实体是否有单独的列表视图,而非必须依赖其余某个实体的视图做为前置条件(好比订单日志必需要先找到订单);

其中,(2)(3)只是做为一个辅助参考,最关键的仍是(1),若是(1)能遵照了,十之八九能够定义为一个独立的聚合了。

相关文章
相关标签/搜索