领域驱动设计之认知篇

学习DDD的意义

作为技术人,都有一个成为大牛的梦。

有些人可以通过自己掌握了比较底层、有深度、有难度的技术来证明自己的能力。

但对于绝大多数的应用研发工程师来说,其大部分的时间精力,会被消耗在读不懂、讲不清的屎山代码中,以及复杂多变的业务迭代中。很少会有需要去接触高深技术的机会,即便是接触了,也很少有实践应用的机会。

所以对于应用研发工程师来说,提高架构设计的能力,预防屎山代码的产生,高效、高质的应对多变的业务需求,便是证明自己能力的关键。而DDD便是一个从业务层面指导架构设计的较为完备的理论体系。

 

DDD诞生的背景

这里我想从我个人的理解,分享下DDD产生的背景。(个人见解)

我们都了解,软件诞生之初,就是几个简单的指令,那时候写代码,真的就是写二进制,通过纸带打孔的方式来交给机器运行。

随着发展,软件指令变得多样,软件也变得复杂,便又有了软件研发上,从汇编语言到高级语言,再到面向对象编程的产生。

软件本身功能的强大还不够,为了应对社会的发展变化,就要求软件自身有更好的扩展性,这便有了设计模式、设计原理等理念的产生。

在社会普遍信息化的今天,软件更是被普及应用在了在各行各业、各种领域。软件面临的复杂度,不再仅仅是技术方案本身的复杂度,更多的是要面对软件所属行业、所属领域的业务本身的复杂度。前者我们称之为偶然复杂度,后者我们称之为本质复杂度。DDD便由此产生。

DDD,中文名字叫领域驱动设计,"领域"一词,表示的是一个业务范围。它强调从业务角度去设计软件。

经典DDD书籍《领域驱动设计:软件核心复杂度应对之道》,这里所说的软件核心复杂度,应该指的就是上文说的本质复杂度吧。

DDD为什么难学

DDD诞生之初,是一个纯粹的理论体系,它包含了各种复杂且难以理解的概念。

在接下来的发展中,又有追捧者根据自己对DDD的理解,发展出不同的落地方案,比如:六边形架构、洋葱架构、CQRS、ES、整洁架构等。这就使得DDD的知识体系更加复杂。

再加上DDD理论本身并不是一个放之四海皆准的方案,需要具体场景具体判断,这就大大提高了DDD的学习应用门槛。所以我经常开玩笑说:DDD最大的价值就是用来吹牛逼。

 

DDD的核心目的

与设计模式在实际研发中的应用一样,DDD的应用也需要我们在合适的场景选择合适的设计。那么如何判断场景合适与否呢?

要回答这个问题,需先搞清楚,DDD的设计理念的核心目的是什么。

DDD标榜自己是治理核心复杂度,但我想问,复杂度为什么需要被治理?复杂度可以通过治理被降低吗?

首先,复杂度为什么需要被治理。这是因为人的认知能力是有限的,当事物的复杂度超出一定范围,就会给人带来认知负荷,阻碍人们对事物的理解。

其次,复杂度能否被降低。个人更倾向于Linus Torvalds所认为的:复杂度并不会因为被治理而降低。比如操作系统,虽有各种设计,但依旧复杂。毕竟要实现的功能摆在那。

复杂度虽然不能被降低,但我们可以通过一些手段,比如分离关注点、封装屏蔽细节等,来降低复杂度给人们带来的理解上的难度。

所以,我更相信,与其说DDD是治理核心复杂度,不如说DDD的核心目的是提高系统的可理解性。

了解了DDD的核心目后,我们就可以通过这样的方式来判断,在某个场景下是否适合引入DDD的某个理念:引入DDD的设计理念后,系统(代码)是否更清晰、更易理解。

这里还需要强调的是:DDD是提高可理解性的手段,可理解性才是核心目的。当在某个场景下,该手段不能帮我们提高可理解性时,那就果断放弃。千万不要为了用DDD而用DDD。

 

关于可理解性

可理解性,也就是我们搞清楚一个事物的难易程度。

其重要性不言而喻:一个难以理解、难以搞清楚的系统,一定是一个难以维护的系统,其迭代效率一定是较低的,Bug率一定是较高的,质量绝对是堪忧的。

根据熵增理论,一个系统如果没有外力的干预,一定会变得越来越杂乱。伴随着系统的杂乱,人们对系统的理解也会变得越来越困难。

所以,个人觉着系统的可理解性的重要性绝不亚于可扩展性,甚至优先级高于可扩展性。

那么DDD有哪些比较关键的手段来提高系统的可理解性呢?我认为有这么几个比较关键的点:统一语言、领域分解、领域建模。

统一语言,它通过边界清晰的、完整一致的抽象命名,来降低人们的认知负荷。犹如人类将所依赖的食物一致的划分为蔬菜、水果、粮食等。

领域分解,它通过分治的手段,实现关注点的分离,从而降低认知负荷。比如,计算机包括了CPU和内存等模块,当你想要搞清楚计算机是如何实现计算的。你只需要把注意力聚焦在CPU上,而几乎不需要被其他模块的实现细节所干扰。

领域建模,它利用面向对象的设计,较为直观的映射业务现实,从而提高可理解性。比如,地球仪就是对地球的建模,如果想清楚的了解地球,地球仪一定比地图更直观。

总结

个人认为,学习一门技术,首先要搞清楚这门技术能帮我们实现什么目标,解决什么问题。接下来才是学习这门技术的具体手法和技巧。只有这样,我们才能在一个清晰的目标下,有目的、有选择的甚至是优化改进的,应用这些手法和技巧。

所以本文主要是认知篇,介绍了DDD的背景和难点,以及重要的DDD能够帮我们实现的核心目标:提高系统的可理解性。

有了本文章的铺垫,下篇文章,我将重点介绍DDD中,那些比较重要、比较有价值的手法和技巧。

 

 

热门相关:骑士归来   法医王妃不好当!   豪门重生盛世闲女   最强反套路系统   横行霸道