领域驱动设计的精髓

体系只有在其轮廓形成时从理念世界的构造本身获得了灵感,它才是有效的。

——瓦尔特·本雅明,《德意志悲苦剧的起源》


领域驱动设计是自成体系的一套软件研发方法论,涵盖了软件开发的全生命周期。它的体系庞大,包容性强,其中诸多模式与原则颠覆了以技术为核心的工程思想,使得领域驱动设计的学习者与实践者常常发出“不得其门而入”之叹。这并非领域驱动设计这套体系的过错,也并非Eric Evans等领域驱动设计大师们故弄玄虚,而是因为针对领域的分析和建模,本身有赖于设计者的行业知识与设计经验。

经验之说,只可意会,不可言传,而领域驱动设计若只有凭借经验才能做好,就不能称为一套方法体系了。为此,我针对领域驱动设计存在的不足,通过固化领域驱动设计的过程,提供更为直接有效的实践方法,建立具有目的性和可操作性的研发过程,即领域驱动设计统一过程(domain- driven design unifiedprocess,DDDUP)。这得益于领域驱动设计的开放性。这种开放性使得它具有海纳百川的包容能力,促进了它的演化与成长,是我提出领域驱动设计统一过程以及诸多实践方法与模式的根基所在。

但是,领域驱动设计毕竟不是一个无限放大的筐,我们不能将什么技术方法都往里装,然后美其名曰领域驱动设计。领域驱动设计是以领域为核心驱动力的设计方法,此乃其根本要旨,也可认为是运用领域驱动设计的最高准则

不仅要遵循这一最高准则,还要抓住领域驱动设计的精髓。如此才能灵活地运用领域驱动设计,避免死板地遵照领域驱动设计统一过程的要求。

20.1 领域驱动设计的精髓

什么是领域驱动设计的精髓?它体现为两个要素:边界与纪律。

20.1.1 边界是核心

无论从问题空间到解空间,还是从战略设计推进到战术设计,领域驱动设计一直强调的核心思想,就是对边界的界定与控制

从全局分析开始,我们就需要确定目标系统的利益相关者与愿景以确定目标系统的范围。它的边界是领域驱动设计问题空间的第一重边界,可以用于界定问题空间;帮助团队明确了哪些功能属于目标系统的范围,也可以在未来需求发生变更或增加时作为团队的判断依据。系统范围边界的大小等于问题空间的大小,也就决定了目标系统的规模。确定系统范围是探索问题空间的主要目的,同时,也是求解问题空间的重要参考。

问题空间通过核心子领域、通用子领域和支撑子领域进行分解,以更加清晰地呈现问题空间,同时降低问题空间的复杂度。子领域确定的边界是领域驱动设计问题空间的第二重边界,帮助团队看清主次,理清了问题空间中领域逻辑的优先级,同时促使团队在全局分析阶段将设计的注意力放在领域和对领域模型的理解上,满足领域驱动设计的要求。

领域驱动设计问题空间的两重边界属于分析边界

到了架构映射阶段,利用组织级映射获得的系统上下文成了领域驱动设计解空间的第一重边界。通过系统上下文明确哪些属于目标系统,哪些属于伴生系统,即可清晰地表达当前系统与外部环境之间的关系、确定解空间的规模大小。

通过业务级映射获得的限界上下文是领域驱动设计解空间的第二重边界,可以有效地降低系统规模。无论是在业务领域,还是架构设计,或者团队协作方面,限界上下文边界都成了重要的约束力。边界内外可以形成两个不同的世界:暴露在限界上下文边界外部的是远程服务或应用服务,每个服务都提供了完整的业务价值,并通过相对稳定的契约来展现服务、确定限界上下文之间的协作方式;在限界上下文边界之内,可以根据不同的需求场景,形成自己的一套设计与实现体系。外部世界的规则是契约、通信以及系统级别的架构风格与模式,内部世界的规则是分层、协作以及类级别的设计风格与模式。

在限界上下文内部,网关层与领域层的隔离成了领域驱动设计解空间的第三重边界。菱形对称架构形成了清晰的内外边界,有效地隔离了业务复杂度与技术复杂度。将领域层作为整个系统稳定而内聚的核心,是领域驱动设计的关键特征。唯有如此,才能逐渐将这个“领域内核”演化为企业的重要资产。这也是软件设计的核心思想,即分离变与不变。领域内核中的领域模型具有一种本质的不变性,只要我们将领域逻辑剖析清楚,该模型就能保证相对的稳定性;若能再正确地识别可能的扩展与变化,加以抽象与封装,就能维持领域模型绝对的稳定性。网关层封装或抽象的外部资源具有一种偶然的不变性。利用层次的隔离,就能有效应对外部形势的变化。

若要维持领域内核的稳定性,高内聚与松耦合是根本要则。虽然职责分配的不合理在网关层的隔离下可以将影响降到最低,但是,总在调整与修改的领域模型是无法维护领域概念完整性和一致性的。为此,领域模型引入了聚合这一最小的设计单元。它从完整性与一致性对领域模型进行了有效的隔离,成了领域驱动设计解空间的第四重边界。领域驱动设计为聚合规定了严谨的设计约束,使得整个领域模型的对象图不再变得散漫,彼此之间的协作也有了严格的边界控制。这一约束与控制或许加大了我们设计的难度,但却可以挽救因为限界上下文边界划分错误带来的不利决策。

领域驱动设计解空间的四重边界属于设计边界

问题空间的分析边界与解空间的设计边界如图20-1所示。

b280d51bbfb58cf7aec0ad8650b22b72.png

             图20-1 问题空间的分析边界与解空间的设计边界

领域驱动设计在各个层次提出的核心模式具有不同的粒度和设计关注点,但本质都在于确定边界。毕竟,随着规模的扩大,一个没有边界的系统终究会变得越来越混乱;架构没有清晰的层次,职责缺乏合理的分配,代码就会变得不可阅读和维护,最终系统会形成一种无序设计

我们看一个无序设计的软件系统,就好像隔着毛玻璃观察事物,系统中的软件元素都变得模糊不清,充斥着各种技术债。细节层面,代码污浊不堪,违背了高内聚松耦合的设计原则,导致要么放错了代码位置,要么出现重复的代码块;架构层面,缺乏清晰的边界,各种通信与调用依赖纠缠在一起,同一问题空间的解决方案各式各样,让人眼花缭乱,仿佛进入了没有规则的无序社会。

领域驱动设计问题空间的两重边界与解空间的四重边界可以保证系统的有序性。

20.1.2 纪律是关键

不管一套方法体系多么完美,如果团队不能严格地执行方法体系规定的纪律,一切就都是空谈。ThoughtWorks的杨云就指出:“领域驱动设计是一种纪律,”他进一步解释道,“领域驱动设计本身没有多难,知道了方法的话,认真建模一次还是好搞的,但是持续地保持这个领域模型的更新和有效,并且坚持在工作中用统一语言来讨论问题是很难的。纪律才是关键。”

领域驱动设计强调对边界的划分与控制。如果团队在实施领域驱动设计时没有理解边界控制的意义,也不遵守边界的约束纪律,边界的控制力就会被削弱甚至丢失。例如,我们强调通过菱形对称架构隔离业务复杂度与技术复杂度,而团队成员在编写代码时却图一时的便捷,直接将网关层的代码放到领域模型对象中,或者为了追赶进度,没有认真进行领域建模就草率编写代码,却无视聚合对概念完整性、数据一致性的保护,领域驱动设计解空间强调的四重边界就形同虚设了。

纪律是关键,毕竟影响软件开发质量的关键因素是人,不是设计方法。对团队成员而言,学习领域驱动设计是提高技能,能否遵守领域驱动设计的纪律则是一种工作态度。需要向团队成员明确一个问题的答案:领域驱动设计到底有哪些必须遵守的纪律?

结合领域驱动设计的知识体系和统一过程,我总结了领域驱动设计的“三大纪律八项注意”,可作为团队的纪律规范。

q三大纪律:

♦   领域专家与开发团队在一起工作;

♦   领域模型必须遵循统一语言;

♦   时刻坚守两重分析边界与四重设计边界。

q八项注意:

♦   问题空间与解空间不要混为一谈;

♦   一个限界上下文不能由多个特性团队开发;

♦   跨进程协作通过远程服务,进程内协作通过应用服务;

♦   保证领域分析模型、领域设计模型与领域实现模型的一致;

♦   不要将领域模型暴露在网关层之外,共享内核除外;

♦   先有领域模型,后有数据模型,保证二者的一致;

♦   聚合的关联关系只能通过聚合根ID引用;

♦   聚合不能依赖访问外部资源的南向网关。

“三大纪律”是实施领域驱动设计的最高准则,是否遵守这“三大纪律”,决定了实施领域驱动设计的成败。“八项注意”则重申了设计要素与规则,并对设计规范进行了固化,避免因为团队成员能力水平的参差不齐导致实施过程的偏差。

当然,针对不同的项目、不同的团队,实施领域驱动设计的方式自然有所不同,在不违背“三大纪律”的最高准则下,团队也可以总结属于自己的“八项注意”,甚至更多的纪律条款。

20.2 领域驱动设计能力评估模型

要实施领域驱动设计,必须提高团队成员的整体能力。团队成员的能力与团队遵循的纪律是相辅相成的:能力足但纪律涣散,不足以打胜仗;纪律严而能力缺乏,又心有余而力不足。培养团队成员的能力并非一朝一夕之功,如果能够有一套能力评估模型对团队成员的能力进行评估,就能做到有针对性的培养。借助领域驱动设计统一过程引入的各种方法与模式,我建立了领域驱动设计的能力评估模型。

领域驱动设计能力评估模型(domain-driven design capability assessment model,DCAM)是我个人对领域驱动设计经验的一个提炼,可以指导团队进行能力的培养和提升。DCAM并非一个标准或一套认证体系,更非事先制订或强制执行的评估框架。建立这套模型的目的仅仅是更好地实施领域驱动设计。我不希望它成为一种僵化的评分标准,它应该是一个能够不断演化的评估框架。DCAM如图20-2所示,目前,它仅限于对象建模范式的领域驱动设计。

图20-2所示的能力维度包括:

q敏捷迭代能力;

q需求分析能力;

q领域建模能力;

q架构设计能力。

f1a75d2f8d2887be5e1fe42f62824449.png

               图20-2 领域驱动设计能力评估模型

根据能力水平,每个维度分为初始级、成长级和成熟级3个层次,各个层次的能力水平围绕领域驱动设计能力开展评估。层次越高,团队的领域驱动设计能力就越高,推行领域驱动设计成功的可能性也就越高。

20.2.1 敏捷迭代能力

我认为,领域驱动设计之所以在近十余年未能取得举足轻重的成功,其中一个原因就是它没有与敏捷软件开发过程结合起来。敏捷开发的诸多实践,包括特性团队、持续集成、迭代管理等都可以为领域驱动设计的实施保驾护航。敏捷迭代能力等级评估标准如表20-1所示。

表20-1 敏捷迭代能力等级评估标准

等级

团队管理

过程管理

初始级

组件团队,缺乏定期的交流制度;没有领域专家或专职的需求分析人员

每个版本的开发周期长,无法快速响应需求的变化

成长级

全功能的领域特性团队,每日站立会议,领域专家参与需求分析活动

采用了迭代开发模式,定期交付小版本

成熟级

自组织的领域特性团队,团队成员定期轮换,形成知识共享,领域专家全程参与,密切与团队进行沟通和协作

建立了可视化的看板,由下游拉动需求的交付,消除浪费

20.2.2 需求分析能力

领域驱动设计的核心驱动力是“领域”,领域主要来自问题空间的业务需求。要从复杂多变的真实世界中提炼出满足建模需求的领域知识和领域概念,就要求团队具备成熟的需求分析能力。需求分析能力等级评估标准如表20-2所示。

表20-2 需求分析能力等级评估标准

等级

需求管理

分析方法

初始级

没有清晰的需求管理体系

没有一套成体系的需求分析方法,只是从功能角度建立需求规格说明书,没有考虑各种用户的业务场景

成长级

定义了产品待办项和迭代待办项

使用了如用例等需求分析方法,形成了严谨而完整的需求规格说明书

成熟级

建立了故事地图,建立了史诗故事、特性与用户故事的需求体系

重视价值需求,在需求分析过程中大量使用可视化工具对业务需求进行探索,快速输出需求规格说明书

20.2.3 领域建模能力

团队成员的领域建模能力是推行领域驱动设计的基础,也是领域驱动设计有别于其他软件开发方法的根本。领域建模能力等级评估标准如表20-3所示。

表20-3 领域建模能力等级评估标准

等级

分析建模

设计建模

实现建模

初始级

采用数据建模,建立以数据表关系为基础的数据模型

领域模型为贫血领域模型,通过事务脚本实现领域逻辑

编码以实现功能为唯一目的,没有单元测试保护

成长级

领域分析建模工作只限于少数资深技术人员,并主要凭借经验完成建模

建立了富领域模型,遵循面向对象设计思想,但未明确定义聚合和资源库

方法和类的命名都遵循了统一语言,可读性高,为核心的领域产品代码提供了单元测试

成熟级

采用事件风暴、四色建模法等可视化建模方法,由领域专家与开发团队一起围绕核心子领域开展领域分析建模

建立以聚合为设计单元的领域设计模型,职责合理地分配给聚合、资源库与领域服务

采用测试驱动开发编写领域代码,遵循简单设计原则,具有明确的手工/自动化测试分层策略

20.2.4 架构设计能力

如果说领域建模完成了对问题空间真实世界的抽象与提炼,架构设计就是在解空间中进一步对领域模型进行规范,建立边界清晰、风格一致的演进式架构。架构设计能力等级评估标准如表20-4所示。

表20-4 架构设计能力等级评估标准

等级

架构

初始级

采用传统三层架构,未遵循整洁架构,整个系统缺乏清晰的边界

成长级

建立了以限界上下文为架构单元的应用架构,领域层作为分层架构的独立一层,隔离了业务复杂度与技术复杂度,并为领域层划分了模块

成熟级

遵循了整洁架构,清晰地定义了系统上下文和限界上下文的边界,具有响应需求变化的演进能力

DCAM评估的这4种能力必须在领域驱动设计研发方法体系下进行,也对应了领域驱动设计统一过程中各个阶段的过程工作流与支撑工作流,是实施领域驱动设计统一过程的能力保障。当然,为了能够将该能力评估模型推广到领域驱动设计社区,我尽量避免将它与我提倡的领域驱动设计统一过程产生绑定关系。为此,我在确定评估标准时,选择了得到领域驱动设计社区普遍认可和推广的实践、方法和模式,由我提出的菱形对称架构、快速建模法、角色构造型、服务驱动设计以及对业务服务的抽象,都未体现在对应能力的评估标准中。

20.3 领域驱动设计参考过程模型

没有一套放之四海而皆准的过程方法能够一劳永逸地解决所有问题,但为了降低实施领域驱动设计的难度,确乎可以提供一套切实可行的最佳实践对整个过程进行固化与简化。这正是我提出领域驱动设计统一过程的主要原因。

领域驱动设计统一过程对领域驱动设计知识进行抽象与提炼,然后以一种标准而统一的过程为开发团队实施领域驱动设计形成指导,它的指导价值不言而喻。但就统一过程本身,它仅仅是一个抽象的过程体系。它虽然规定了在什么阶段应该采用什么样的工作流,但体系自身并没有确定究竟该用什么样的方法与模式帮助团队顺利地实施工作流。

为了帮助团队更好地实施领域驱动设计,有必要针对领域驱动设计统一过程做进一步的固化与简化,结合我个人实施领域驱动设计的经验,选择部分行之有效的方法与模式,填充到领域驱动设计统一过程的空白处,形成一套领域驱动设计参考过程模型。这套过程模型不能解决实施过程中的所有问题,也无法规避需要凭借经验的现实问题,但通过一些真实项目开发实践得到证明,它能够在一定程度降低实施门槛,从战略和战术层面获得高质量的领域模型。这一参考过程模型如图20-3所示。

整个参考过程模型通过业务流程泳道图体现,每个泳道代表领域驱动设计统一过程的一个阶段,矩形的流程图例代表领域驱动设计统一过程运用的方法或模式,文档图例代表融合了领域驱动设计模式的输出工件,虚线空心箭头为输入流,实线实心箭头为输出流。

从需求调研开始,参考过程模型建议使用商业模式画布对问题空间进行探索,获得利益相关者、系统愿景和系统范围,它们共同构成了目标系统的价值需求。根据价值需求的利益相关者,运用服务蓝图业务流程图对业务需求进行梳理,获得业务流程。对业务流程按照业务目标进行时间上的阶段划分,就可以获得业务场景。对业务场景进一步分析,可以获得代表服务价值的业务服务。业务流程、业务场景和业务服务共同构成了目标系统的业务需求。

在系统愿景与系统范围的指导下,利用功能分类策略对问题空间进行分解,获得由核心子领域、通用子领域和支撑子领域组成的子领域。

参考全局分析阶段确定的价值需求,绘制业务序列图,通过C4模型的系统上下文图最终确定系统上下文。它确定了整个解空间的边界,明确了目标系统的解决方案范围,有助于我们确定哪些系统是目标系统、哪些系统是伴生系统,也确定了利益相关者、目标系统、伴生系统之间的关系。在系统上下文边界的约束下,以V型映射过程对业务服务表达的领域知识进行归类和归纳,获得体现业务能力的限界上下文,并运用菱形对称架构体现限界上下文的内部架构。需求分析人员在编写了业务服务规约之后,针对业务服务绘制服务序列图,结合业已识别出来的限界上下文,确定上下文映射模式,并为目标系统定义服务契约。最后在系统上下文边界的约束下,根据子领域和限界上下文之间的关系,确定系统分层架构。

ca469f1615ae05026744421fd7c153ee.png

                图20-3 领域驱动设计参考过程模型

领域建模需要在限界上下文的边界约束下进行。建模的前提是业务分析人员已经将全局分析阶段输出的业务服务细化为业务服务规约,在统一语言的指导下对其采用快速建模法获得领域分析模型。以领域分析模型为基础,运用聚合设计的庖丁解牛过程获得以聚合为核心要素的角色构造型,获得静态的领域设计模型。对业务服务开展服务驱动设计,根据业务服务规约定义的基本流程,将业务服务分解为任务树,分配职责获得序列图脚本,从而获得动态的领域设计模型。按照业务服务规约定义的验收标准,为任务树的每个任务编写测试用例,开展测试驱动开发,从而获得领域实现模型。领域分析模型、领域设计模型和领域实现模型共同构成了在限界上下文边界约束之下的领域模型,实现了战略设计与战术设计的融合。

领域驱动设计参考过程模型为领域驱动设计统一过程的每个阶段每个环节提供了具有实操性的方法和模式,也规定了每个阶段需要输出的工件。不过,我们还需要一个完整案例真实地展示它如何指导团队从问题空间走向解空间,最终获得高质量领域模型的过程。为此,我选择了一个中等规模的真实案例,全方位地展现在项目中如何实践领域驱动设计参考过程模型。这个真实案例就是企业应用套件(enterprise application suite,EAS)。

本文摘录于张逸老师新书《解构领域驱动设计》。

❀❀❀

0746f7ee9ffd4f09444d757eb060bf36.jpeg

☼ 本文为《解构领域驱动设计》第一章内容,可在京东、当当、淘宝等电商平台上搜索书名,购买本书。

本书全面阐释了领域驱动设计(domain-driven design,DDD)的知识体系,内容覆盖领域驱动设计的主要模式与主流方法,并在此基础上提出“领域驱动设计统一过程”(domain-driven design unified process,DDDUP),将整个软件构建过程划分为全局分析、架构映射和领域建模3个阶段。除给出诸多案例来阐释领域驱动设计统一过程中的方法与模式之外,本书还通过一个真实而完整的案例全面展现了如何进行领域驱动设计统一过程的实施和落地。为了更好地运用领域驱动设计统一过程,本书还开创性地引入了业务服务、菱形对称架构、领域驱动架构、服务驱动设计等方法与模式,总结了领域驱动设计能力评估模型与参考过程模型。本书提出的一整套方法体系已在多个项目中推广和落地。
本书适合希望领会软件架构本质、提高软件架构能力的软件架构师,希望提高领域建模能力、打磨软件设计能力的开发人员,希望掌握业务分析与建模方法的业务分析人员,希望学习领域驱动设计并将其运用到项目中的软件行业从业人员阅读参考。


加入技术琐话粉丝群,可在公众号回复:技术群

  往期推荐:

技术琐话 

以分布式设计、架构、体系思想为基础,兼论研发相关的点点滴滴,不限于代码、质量体系和研发管理。

5b9302c2d1bd650c37bafa9acbfe3b07.jpeg

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值