领域驱动设计 (DDD) 简介 - jannikwempe


领域驱动设计是您应该了解的概念——无论您是开发人员还是领域专家。使用 DDD 处理复杂的软件项目。
领域驱动设计 (DDD) 的概念是由 Eric Evans 提出的。早在 2004 年,他就在他的著作领域驱动设计(又名“蓝皮书”)中写到了这一点。
 
DDD 上下文中的域是什么?
一种知识、影响或活动的范围。
我将向您概述 DDD 的全部内容。这篇文章是关于“为什么?” 和“什么?” 的 DDD。我不会在这里深入探讨特定主题。尽管如此,我还是会指出一些重要术语的定义,就像我刚刚对“域”所做的那样。正如您将意识到的,共享词汇也是 DDD 本身的一部分。
 
今天 DDD 还有用吗?
DDD 不是关于某种技术,它是一个更现代的概念。Sam Newman 所著的《构建微服务》一书第一页的快速引用:
Eric Evan 的书 DDD 帮助我们理解了在我们的代码中表示现实世界的重要性。并向我们​​展示了更好的方法来为我们的系统建模。
此外,IBM Garage Event-Driven Reference Architecture有一章关于方法论 DDD。
回答有关相关性的问题:直到今天,它确实非常有效。随着最新的进展,让我们继续探索“为什么?” 和“什么?”
  
为什么会存在 DDD?
为什么甚至需要像 DDD 这样的东西?Eric Evans 书的副标题提供了一个非常好的提示:
解决软件核心的复杂性
通常,软件项目的关键复杂性在于领域本身。您无法更改领域内的复杂性。您可以尝试在银行柜台告诉客户,您只只专注于支付,而不是贷款业务,因为它太复杂了。
此外,我们不只是为了开发软件而开发软件。我们这样做是为了解决问题和改进事情:
软件的核心是为用户解决领域相关问题的能力。所有其他功能,尽管它们可能很重要,但都支持这个基本目的。
 
DDD 是什么?
那么究竟什么是 DDD?DDD 不能用一两句话来定义。它是一种开发由多个拼图组成的复杂软件的方法:

  1. 集中在核心的复杂性和机会领域
  2. 与领域专家和软件专家合作探索模型
  3. 在有限的上下文中说一种无处不在的语言

(注意斜体字。这些是 DDD 中的特定术语,我将像定义域一样定义它们。)
这三点已经是对 DDD 的一个非常高级的总结,但我将在接下来的部分中一一介绍。
 
专注领域
集中在核心的复杂性和机会领域
核心复杂性和机会可能不同于我们所说的“业务”。想想推特:提供推文的功能、相互关注等并不是主要的复杂性。很可能主要的复杂性在于扩展该平台。
 
探索模型
与领域专家和软件专家合作探索模型
模型是处理上述复杂性的一种方式。但是,首先,什么是模型?
 DDD 上下文中的模型是什么?
一个抽象系统,描述域的选定方面并可用于解决与该域相关的问题。
描述该术语的另一种方式(也来自埃里克·埃文斯本人):
模型是一种简化。它是对现实的一种解释,它抽象了与解决手头问题相关的方面并忽略了无关的细节。
它不是图表(因此也不是实体关系图(ERD)——尽管实体也是 DDD 中使用的一个术语)。图表只是帮助传达模型。您会在 DDD 的上下文中看到很多图表。没有特定的、唯一的建模语言。大多数情况下,使用一些类似 UML 的图表或只是手写草图。这不是关于图表,而是关于它背后的概念。
动词“探索”是故意选择的,而不是像“写下来”这样的词语。获得模型将是一个迭代过程。没有一劳永逸地完成模型这样的事情。将有新的见解、新的或不断变化的问题出现在该领域或其他任何方面。这是一个持续的探索。
 
案例:模型示例
想想典型的世界地图(有点像图表)。世界标准地图显示的是墨卡托投影。你们中的大多数人都知道这张地图不是关于不同国家的大小或类似的东西。它是专门为海上航行而创建的。您可以在地图上的点之间画一条线,并知道如何使用指南针导航。
这是地图后面的实际模型:

Eric Evans 在他 2019 年的会议演讲中使用的这个例子是一个很好的例子。它指出模型与手头的问题直接相关。
 拥有模型实际上并没有给你任何优势。优势并非来自拥有模型。优势来自于拥有一个非常适合您要解决的特定问题集的模型。
模型必须在“领域专家和软件专家的合作”中进行探索。领域专家创建模型和开发人员都不会将他们的 ERD 作为模型出售。协作探索模型的过程被 Eric Evans 称为“Knowledge Crunching”。
最后用 Eric Evans 的两句话来表达最重要的一点来结束本节:
本书的主旨是一个模型应该强调实施、设计和团队沟通。为这些不同的目的使用不同的模型会带来危险。

如果编写代码的人不觉得对模型负责,或者不了解如何使模型为应用程序工作,那么模型与软件无关。如果开发人员没有意识到更改代码会改变模型,那么他们的重构将削弱模型而不是加强模型。
这些要点是:代码和模型直接相关。
 
说一种无处不在的语言
在有限的上下文中说一种无处不在的语言。
在 DDD 的上下文中,无处不在的语言是什么意思?
一种围绕领域模型构建的语言,供所有团队成员 在有界上下文中使用,以将团队的所有活动与软件联系起来。
其中还有一个值得定义的术语:有界上下文:
上下文: 单词或语句出现的语境决定了其含义。 关于模型的陈述只能在上下文中理解。

有界上下文:对边界(通常是子系统或特定团队的工作)的描述,在该边界内定义和适用特定模型。

值得注意的是,“无处不在”的语言在适用于系统范围的意义上并不是无处不在的。而是在代码、语音、图表等中使用。这也是添加“在有界上下文中”限制的原因。该语言将适用于您必须明确定义的边界。这不是跨界定义术语,例如为整个公司定义术语。例如,在营销或仓库环境中,甚至可能在仓库环境的不同部分,使相同东西可能非常不同。

用我自己的话来说:泛在语言是一种与给定领域模型直接互连的通用语言,它在您定义的边界内随处使用。“与模型直接互连”的部分揭示了语言的变化也应该与模型的变化直接相关。事实上,模型应该使用领域专家已经使用过的术语来创建。
[...] 语言的更改将被识别为域模型的更改,并将引导团队更新类图并重命名代码中的类和方法 [...] 使用模型作为语言的支柱。[...] 在图表、写作,尤其是演讲中使用相同的语言。
太好了,现在我们知道这个词是什么意思了,但为什么这很重要?本书的这一部分给出了原因的印象:
在没有通用语言的项目中,开发人员必须为领域专家翻译。领域专家在开发人员和其他领域专家之间进行翻译。开发人员甚至可以互相翻译。
我敢打赌,您遇到过这样的情况,您作为开发人员不知道领域专家在说什么,甚至更糟的是,您认为自己知道但他/她在谈论其他事情。反过来也是一样。
使团队习惯于询问所使用的特定术语的含义。团队必须在所有沟通中坚持使用无处不在的语言。领域专家正在谈论给定领域中未反映在模型中的概念?模型可能不完整。
无处不在的语言将导致代码和实际领域更接近。它不仅与反映实际领域的代码有关,它还具有许多其他积极方面。考虑代码的可维护性。如果另一位开发人员在一段时间后返回代码,则会在域中使用术语。领域专家确实了解所使用的术语,他们不仅仅是具有由开发人员组成的名称的类。
 
结论
DDD 仍然是您工具箱中的一个重要概念。它已经影响了许多其他领域(查看 JPA 规范的 JavaDoc)并且仍在影响它们。
解决领域的问题是开发软件的全部意义所在。我们必须处理这种复杂性。但是我们可以通过应用 DDD 来处理这种复杂性,从而使我们的生活更轻松。