翻遍整个互联网,我发现,关于领域驱动设计,大家都**理解错了**。
今天,我们尝试通过一篇文章的篇幅,给大家展示一个完全不同的视角,把“领域驱动设计”这六个字解释清楚。
## 领域驱动设计学习资料现状
领域驱动设计的概念提出已经有20年的时间了,整个互联网充斥着大量书籍、文章和视频教程,这里我列举几本比较著名的优秀书籍:
- 领域驱动设计之父 Eric Evans《领域驱动设计-软件核心复杂性应对之道》
- Vaughn Vernon的《实现领域驱动设计》
- 张逸老师的《解构领域驱动设计》
首先不可否认,这些书籍都是优秀的作品,也被业界奉为宝典级别的作品,网上大部分资料的核心内容也都是类似的,但我相信,大部分人读这些资料的感受是:
- 晦涩难懂
- 不明觉厉
## 为什么会云里雾里不明觉厉?
首先,我先列举出了大部分文章提到的概念名词:
- 问题空间(problem space)
- 解决方案空间(Solution Space)
- 领域(Domain)
- 限界上下文(Bounded Context)
- 通用语言(Ubiquitous Language)
- 实体(Entity)
- 值对象(Value Object)
- 聚合(Aggregate)
- 仓储(Repository)
- 工厂(Factory)
- 领域服务(Domain Service)
- 领域事件(Domain Event)
目前主流的领域驱动设计资料(书籍、文章、课程),都在尝试将这些概念给读者讲明白,都在尝试解释这样的方法是好的方法,但很显然都没有站在一个不懂领域驱动设计的开发者角度来讲解,要理解这些资料所讲述的观点,是需要先理解“领域驱动设计”,然后才能看得懂,甚至出现领域建模需要“凭经验”这样的说法。
所以说目前大部分的资料,懂领域驱动设计的人才能看懂,而懂的人,又不需要通过这些资料获取养分,这就变成了一部分人的自娱自乐。
由于大部分人在了解领域驱动设计的过程中,更多的感受是“晦涩难懂”、“不明觉厉”,导致整个软件行业对它产生了两级分化的评价,一部分人认为领域驱动设计完全没用,不可落地,一部分人却认为这是软件工程困境的解药,而且处于这两极的开发者,不仅观点无法调和,甚至在辩论过程中,也是驴唇不对马嘴,完全无法在一个频道上沟通和交换观点。
## 领域驱动设计到底是什么?
【视频】[全网第二个把 DDD 说明白的视频](https://www.bilibili.com/video/BV1AZ421M7zw)
先说观点:**领域驱动设计** **是一种价值观**。
领域驱动设计不是方法论,不是软件设计时的思想指导,不是代码组织的灵丹妙药,它本质上是一种价值观,是你做一个决策时的价值取向。
接下来,咱们把“领域驱动设计”这六个字拆解出来分析。
首先什么是“领域”?英文原词就是“Domain”,这个词并不抽象,就是其直接的含义,就是边界、范围的意思。比如一个篮球场的范围,一个国家的领土范围,一个公司前台的工作职责范围,又或者是一个软件系统提供的功能的范围。
然后是“驱动”,怎么理解呢?我们看看下面几句话:
- 赚钱驱动工作
- 欲望驱动求偶
- 领域驱动设计
这三句话的句式是类似的,解读起来就是:工作的目的是赚钱,所以赚钱这个目的驱使我们工作,我们世俗的欲望驱使我们求偶,那么识别(问题、解决方案)的范围/边界这个目标驱使我们进行分析和设计行为。所以“驱动”的意思是为了xx的目标而做yy。
最后是“设计”就是指我们分析需求、设计模型、组织代码的行为。
到这里,“领域驱动设计”这个词表的的意思,就是我们做软件设计的核心驱动力,就是识别各种各样的范围和边界。如果你认同这个观点,就意味着你认为“识别领域”是软件设计的核心目标,是软件设计最重要的事情。
什么是最重要的事?就是你的价值取向,就是价值观。而价值观又恰恰是人们做各种决策的底层因素。
这里举个例子,有的人出门喜欢打车,图方便,方便就是ta看重的价值,有的人出门喜欢自行车,可以锻炼,锻炼就是ta看重的价值,看重不同的价值,在做“选择交通工具”这个决策时,起了决定性作用,最终做出的决定也是不同的。
因此,我们认为价值观决定了做决策时看重什么,而“领域驱动设计”的价值观,就是识别领域是最重要的事,我在分析业务、建模过程中,一定要识别出范围和边界,不识别出来我就不舒服。
当然也有很多与“领域驱动设计”不一致的价值观,比如为了赶工期,“这块没搞清楚,先凑合一下,以后再说”,也是一种常见的软件设计价值观的体现,这是“工期大于一切”的价值观。
当然,很多人会说把需求完全分析清楚也是不现实的,诚然这个是没错的,因此“领域驱动设计”追求的领域的“明确性”,而不是“正确性”,只要我们在做决策的时候,明确哪部分范围是确定性的,哪部分范围是模糊的,模糊的部分当下被我们明确地划分到了哪个部分范围内。毕竟老板、产品经理、研发都是在有限地信息下做决策,不可能全知全能,一定有一部分地决策是做一定地预判,只要我们明确地知道不明确的部分处于怎样地范围即可,未来随着信息的越来越充分,不断修正我们对领域划分的决策即可。
## 为什么这个价值观符合软件设计的价值利益
【视频】[为什么 DDD 符合软件设计的价值利益](https://www.bilibili.com/video/BV19b421H7wc/)
首先,先来思考一个经典问题:“把大象放进冰箱,一共需要几步?”
第一步,打开冰箱门;第二步,把大象放进去;第三步,关上冰箱门。
我们在解决任何问题的时候,都会遵循一个模式:“大问题拆成小问题”。
而这个模式等价于:“复杂问题变为简单问题”。
那么最关键的问题来了,如何衡量“复杂”和“简单”?我们来看几个例子,下面两个系统,你觉得哪个更复杂?你一定会选“系统2”,因为显然它的元素数量更多。
下面两个系统呢?是不是感觉“系统3”更复杂?
基于上面的例子,我们至少可以得出两个判断:
1. 系统复杂度与元素的数量和元素的关系有关;
1. 元素的关系对系统复杂度的影响远远大于元素的数量所产生的影响;
回归到领域驱动设计,为啥要划分领域?因为“划分领域就是在用数量简化关系”,用明确的边界将问题拆解,逐个击破。其意图是控制系统复杂度,尽可能降低系统的复杂度,而复杂度的降低,是与我们软件工程的投入产出利益一致的。
到此,我们就形成了一个核心逻辑链条:“划分领域->降低复杂度->降低成本”,因此划分领域符合我们价值取向,我们愿意认同“领域驱动设计”的价值观。
## 重新审视对待“领域驱动设计”的分歧
假如你认同“领域驱动设计是一种价值观”这样的观点,我们重新来回到前面说的“完全没用,不可落地”和“软件工程困境的解药”这两派观点的分歧上,就会发现大家的分歧底层就是价值观的分歧,一方面大家的讨论维度都停留在“领域驱动设计怎么落地”这个层面,缺少了“领域驱动设计到底是什么”这个问题的共识;另一方面大家没有察觉到核心分歧其实是价值观的分歧,导致了对于“领域驱动设计”的理解和判断过程缺乏底层认知的共识。
对于本质没有共识,其之上的所有讨论如同“空中楼阁”,缺乏严密逻辑链条的推导,那么表达者不得不用一些抽象的概念来模糊化自己表达的东西,从而使得“领域驱动设计”这个词变得越发抽象,越发“不明觉厉”。
## 后续
本文从why的角度解析了“领域驱动设计”,并未涉及到How的部分,但以我的经验来看,理解了why,在执行How的操作时会更加地笃定和自信,更容易成功。
且听我后续慢慢道来。
通过小demo的方式跟大家分享一下我对DDD中战术层级的理解,算是抛砖引玉,该理解仅代表我个人在现阶段的一个理解,也可能未来随着业务经验深入,还会有不同的理解。