领域驱动设计:做正确的事


任何给定软件项目的成功都可以归结为一个相当简单的定义或规则:我们需要构建正确的东西,我们需要正确构建这个东西。

这是一个非常抽象和简单的定义,即使不是原始的定义。然而,这是一个很难争论的问题。

做正确的事情
构建正确的东西……我认为没有必要强调这种说法的重要性。但谁知道正确的事情是什么样子的呢?
领域专家知道吗?

领域专家不是一个真正的职位,而是一个源自扎实行业背景的头衔。它可能来自直接经验,通过在该领域的实际工作获得(例如医生、飞行员、会计师)。或者间接的,通过与其他领域专家(设计师、开发人员、业务分析师)长期合作获得。

领域专家可能甚至将具有不相关的角色和职责,但他们都有一个共同点……领域知识。

在高度复杂的领域,我们可以发现另一层人,其唯一目的是帮助与领域专家的经验和期望进行交互。这些人不可避免地会自己成为领域专家,获得很多间接经验。

您可以通过他们使用的语言来区分领域专家。起初听起来可能相当混乱。充斥着术语、丰富的首字母缩略词和双义词。

领域专家会使用领域语言(专业俚语)。小心,它往往会伪装真正的含义,误导你理解它的错觉。不要犹豫,澄清任何模糊的细节,因为它可能会打开一个全新的意义和理解水平。

把事情做好
没有人喜欢损坏的软件……

总是有很多方法可以解决问题,因此可以构建应用程序。这是开发人员中众所周知的问题,注意力很容易从项目的最终目标转移到最终技术。

技术的选择必须由架构驱动。架构必须由公司的组成以及项目的战术和战略目标来驱动和增强。

专注于项目目标的平衡、不断完善的架构是正确构建事物的关键。

根据大型项目的规模,可能会有不同角色和职位的混合体,他们将密切关注架构和技术堆栈的完整性和一致性。解决方案架构师、技术主管、CTO,应有尽有。
毫无疑问,您会在他们中间找到领域专家,通常他们在一家公司或特定行业拥有悠久的历史。当然,他们会使用可区分的(领域)语言。

为什么要把正确的事情做好这么难呢
看来,大多数时候我们知道如何构建正确的东西,并且我们有领域专家可以为其提供所有必要的支持。我们知道如何正确构建事物,并且我们拥有软件工程力量来促进它。那么,为什么要把正确的事情做好这么难呢?

我认为这里不会有意外,沟通很难……
任何设计系统的组织都会产生一个设计,其结构是组织沟通结构的副本。— 梅尔文·E·康威

所谓的康威定律指出,人与人之间的交流沟通方式会显着影响架构、设计和代码库。

在每个角落都有大量错综复杂的逻辑的复杂领域中,即使是最初无意的错误传达也会使项目脱轨。

任何误解,如果不及时解决,就会引发不匹配的滚雪球效应。
它增长迅速,造成混乱和挫败感,并降低代码库质量,很快变得无法维护和容易出错。
即使最初的错误沟通得到了解决,通常也为时已晚,项目注定失败。

沟通差距
最初的错误传达通常源于领域专家的偏见和开发人员不愿澄清细节。

由于领域专家在某个领域的丰富经验,很多重要的细节是显而易见的,某些方面已经给出并且不需要澄清,如果没有提及的话。语言中充斥着晦涩难懂的首字母缩略词和表达不雅含义的词语。
这是预料之中的,也是不可避免的。

领域语言是领域专家凭借多年经验养成的习惯。这是他们用来进行有效沟通的框架。
医学、数学、会计、工业设计任何专业领域都会有丰富的术语。学术或专业书籍,不能保证领域语言的定义,尽管它们很可能体现其本质;您将从领域专家那里听到什么是领域语言……

一般的沟通和具体的澄清是一个非常费力的过程,需要体面的自我努力。减少认知工作和保存智力资源是人性的一部分。没有动力的开发人员不会尝试澄清术语或可疑词,或解决定义中的歧义。相反,我们下意识地尝试自我解释任何逻辑缺陷或不确定性,忽略不明确的首字母缩略词,并且不质疑晦涩的逻辑或突然的结论。

在领域专家对话中,视觉工件(例如领域模型图)通常会变得非常有用。它提供了清晰的视觉表示,并有助于调整每个人的理解。它可以从简单开始,但会随着时间的推移而成长和改进。

不幸的是,经验丰富且可靠的领域专家以及才华横溢的软件工程师并不能保证项目的成功。

领域驱动设计
可以从不同的角度对 DDD 有不同的理解。它是一种哲学、一个框架、一套架构模式,以及更多的东西,其最终目的是把正确的事情做对。

领域驱动设计 (DDD) 旨在弥合领域、模型和实现之间的差距。它旨在通过使领域模型成为沟通和实施过程的核心来克服那些能够构建 正确事物的人和那些能够正确构建事物的人之间的误解。

1、整体领域模型
领域模型是领域驱动设计的根元素,一切都围绕着它展开。然而,它常常被混淆为一个封装一切的大图。虽然拥有一张大图并没有错,但我们都喜欢大图;除了也许我们不想让它们保持最新状态,但我想那是另一回事了。

事实上,图表是领域模型的重要组成部分,但无处不在的语言、代码库,甚至你和你同事的心智模型也是如此。理想情况下,这应该都匹配并代表整体领域模型。

拥有整体领域模型可能会导致意想不到的结果。在最低限度的支持下,领域专家应该能够阅读并理解代码。因为变量名、类和抽象是域模型的一部分,因此对每个相关人员都有意义。

下面两种代码哪个能更直接表达业务:
将积压项目提交给冲刺

backlogItem.setSprintId(sprintId);
backlogItem.setStatus(BacklogItemStatusType.COMMITTED);

与下面代码:

backlogItem.commitTo(sprint);

很显然是第二个。

其他
DDD 严重依赖面向对象的概念,它在经典对象模型之上构建了丰富的对象抽象。DDD 引入了某种对象分类,例如 Entities 和 Value Objects。提供Aggregates、Aggregate Roots等隔离工具和交互接口。

与许多现代方法不同,DDD 不欣赏贫血模型并将其定义为反模式。它强调了将域对象与域逻辑保持在一起的重要性。所以类知道它们是什么以及它们可以做什么,而不是成为数据传输对象。

DDD 认识到每个领域的复杂性,因此不会试图将所有内容都放在一个碗里。它强调了不同背景之间隔离和界限的重要性,并引入了一组模式来构建反腐败层。

DDD 通常与事件溯源和事件驱动架构配合得很好。