解决DDD最大难题-如何划分领域

本文书接上回《反DDD模式之"复用"》,关注公众号(老肖想当外语大佬)获取信息:

  1. 最新文章更新;

  2. DDD框架源码(.NET、Java双平台);

  3. 加群畅聊,建模分析、技术实现交流;

  4. 视频和直播在B站。

背景

最近直播的时候,看到一条留言,问我是否有关于如何划分领域的文章,翻看了一下,发现关于这么重要的问题,居然没有专门、认真、细致地讲过。也难怪不少人说不接地气,整天搞些虚头巴脑的东西。但没有讲的原因,我还是要为自己辩解几句的,不是不想讲,也不是不能讲,而是我潜意识里觉得本质的东西讲明白了,这个问题就太简单,没必要讲。

当然,如果你是我的老粉丝,关注过我过往输出的内容,那么你也知道,早前也是有在我们FireUG社区的DDD公开课里专门讲这个话题(【DDD 领域驱动设计 | PART V:如何识别领域边界?】 https://b23.tv/sRqAC8O )。

时至今日,我自己对于软件工程的认知又经过了一轮迭代,重新来解读一下这个问题。

先说答案

问:如何划分领域?

答:基于如下两条可以得出一个领域:

  1. 当你有一个需求,叫创建xxx时,那么这个xxx就是一个聚合根;

  2. 我们可以视作一个聚合根就是一个领域;

如何解读

例如,一个系统中,需要创建一个用户,那么用户就是聚合根,用户就是一个领域,诸如此类的需求是非常容易识别的,我相信不论你的软件设计经验如何,都是可以基于这个规则来做出判断的。

当然你会说,我有一个需求是给用户创建收货地址,那么这个收货地址是不是聚合根呢?这就要看,你创建的是"收货地址",还是"用户的收货地址",如果你认为是"收货地址",那么它就应该是聚合根,如果你认为是"用户的收货地址",意味着这个需求,仅仅是给"用户的收货地址属性"添加新值。

又比如订单,你是认为是"创建订单"还是"用户的订单"呢?我想大部分人会直觉上选择"创建订单",为什么会有这样的直觉?我想,你一定会得出一个答案,"订单"足够复杂。

那么这样看来,理解业务的标准是不是又变成了"复杂的就分开"这么一个不太好衡量的判断呢?不妨你把它反过来看,就有答案了,那就是"简单的就合并"。

还是前面的例子,还是收货地址,因为存在一个需求叫"创建收货地址"或者"创建用户的收货地址",我分不清楚,没关系,我们就默认视作存在这个聚合根,存在"收货地址"这个领域。然后我们在考虑,这个领域独立存在对我们有没有好处,这个领域合并进"用户"领域,我们是否可以接受。如果我们有充分的把握说合并没有问题,那么就合并,否则,就让它成为一个领域,并保持边界明确。

为什么基于创建xxx来判断

也许,你会有疑问,为什么基于"创建xxx"需求来判断聚合根?核心逻辑就是这类需求,意味着xxx不可分割的整体,意味xxx就是最小的完整范围,相当于我们基于这类需求,识别出了系统内的"原子单元",就像一片片乐高积木一样,不可再拆分。

本质是什么

在我看来,这样划分领域的方法的本质,就是我们先认为边界就在那里,凡是有创建xxx的需求,即存在一个领域,只是说我们经过思考,某些领域合并进去是比较确定复杂度是可以掌控的,那么我们才做出了合并领域的决定。

所以,与其说这是如何划分领域,不如说,这是思考什么时候合并领域。

底层价值观的支撑

如果你是跟随本系列文章一路阅读过来的话,一定知道,我对于软件设计的核心观点是:

  1. DDD是一种价值观

  2. 保持边界明确是最重要的事

那么你就会发现,前面说的方法,是完全契合这个价值观的,我们首先明确出组成系统的一个个"原子单元",识别出它们,然后再谨慎地进行合并,在没有把握的情况下,优先保持领域边界明确,避免它们之间的耦合。

而信奉这个价值观的依据则是我们对于复杂度的理解,这在前文也有详细讲解:

  1. 系统复杂度与元素的数量和元素的关系有关;

  2. 元素的关系对系统复杂度的影响远远大于元素的数量所产生的影响;

说到底,核心目的仍然是为了保持我们对系统复杂度的掌控,因此我们谨慎地为系统内的领域之间"建立耦合"。

完整操作方法

那么,如果你和我一样,认同DDD是价值观,保持边界是最重要的事,我们完整的操作方法就是:

  1. 当你有一个需求,叫创建xxx时,那么这个xxx就是一个聚合根;

  2. 我们可以视作一个聚合根就是一个领域;

  3. 当我们非常大把握可以掌控一个领域合并后的复杂度时,可以考虑合并这两个领域;

结尾

以上就是我们团队日常分析需求、设计方案和建模的实际操作方法,如果你赞同或者有共鸣,也很期望您将文章分享给更多的朋友。如果你持有不同的观点和视角,也欢迎与我讨论,我相信,至少持续提升开发者幸福感这个方向,咱们是有共识的。

相关推荐
老肖相当外语大佬3 天前
懂了这个道理,人月神话不再是神话!
ddd·领域驱动设计·人月神话·交付效率
小码编匠13 天前
领域驱动设计(DDD)要点及C#示例
后端·c#·领域驱动设计
MQLYES20 天前
01.如何用DDD重构老项目
重构·ddd
rolt20 天前
[pdf,epub]105页《分析模式》漫谈合集01
ddd·架构师·uml·领域驱动设计·分析模式
rolt1 个月前
[答疑]是不是互联网更适合用DDD
ddd·领域驱动设计
rolt1 个月前
有向无环图的约束怎么表达-《分析模式》漫谈39
ddd·uml·领域驱动设计·面向对象
老肖相当外语大佬2 个月前
反DDD模式之“复用”
开源·实战·ddd·领域驱动设计
xin4972 个月前
领域模型和数据模型还傻傻分不清? 如何实现领域模型
后端·领域驱动设计
老肖相当外语大佬2 个月前
反DDD模式之关系型数据库
ddd·领域驱动设计·关系数据库·三范式