庆祝领域驱动设计 (DDD) 和EIP诞生20多年


二十年后,《领域驱动设计》和《企业集成模式》依然是信息技术领域中至关重要的经典书籍,因为它们关注的是概念和折衷方案,而不是特定的技术。

DDD和EIP的相关性得以持续,因为它们不仅简化了复杂系统的设计和开发过程,还适用于微服务模式。

在过去20年中,DDD已成为减少微服务设计复杂性的默认方法,而EIP则减少了实施这些设计的复杂性,尤其是事件或“消息”的实施。

  • 根据微软的说法:领域驱动设计(DDD)是一系列原则和模式的集合,可以帮助开发人员打造优雅的对象系统。正确应用它可以产生称为领域模型的软件抽象。这些模型封装了复杂的业务逻辑,缩小了业务现实和代码之间的差距。
  • 与此同时,亚马逊关于这本书的简介称, 《企业集成模式》提供了一致的词汇和视觉符号框架来描述跨多种技术的大规模集成解决方案。它提供了 65 种模式的目录,以及实际的解决方案,可帮助工程师为其企业设计有效的消息传递解决方案。

然而,尽管发生了很多变化,这些经典书籍中的设计模式、原则和实践在 20 年后仍然非常重要——在某些方面比以往任何时候都更重要。

  • 2022 年 12 月 31 日,亚马逊上对DDD的评论称:“一本关于创建 API 的好书。读完这本书后,我感觉自己在如何创建 API 方面远远超出了同龄人。”
  • 同样,亚马逊最近对EIP的评论说:“现在是 2023 年了,这本书仍然有意义……因为这本书不是关于任何特定的技术,而是关于解释你可以一次又一次接触到的模式。”

有趣的是,这两本书都明白组件设计和集成是齐头并进的。例如,

  • DDD的聚合模式警告分布式事务的共享数据库锁定方案的危险。
  • 同样,EIP不仅仅是设计方案的列表,而且已经成为DDD 提出的面向消息集成的通用语言。

DDD 和EIP是非常契合的对手:

  • EIP 专注于帮助多个应用程序作为一个整体协同工作,
  • 而 DDD 展示了如何在应用程序中对域功能进行建模。

EIP中形式化的模式列表是多个成功的商业集成产品的基础,例如Mule、Camel和WSO2 Micro Integrator。这些产品中的每一个都为模式提供了特定于领域的语言模板,将设计模式转变为可执行的领域语言。

DDD 和EIP在过去二十年中都已被证明可以简化复杂系统的设计和开发流程,并且最近被证明非常适用于微服务模式。

单体与微服务的争论
参与争论的每个人都同意的一件事是微服务的复杂性。这种复杂性分为两个维度:业务领域固有的复杂性和构建和操作分布式系统的技术复杂性。

正如Martin Fowler 在DDD简介中提到对软件系统复杂性的普遍抱怨时所说 “……这种复杂性的核心是问题域本身的本质复杂性。”

换句话说,自动化业务功能很复杂,因为业务功能本身很复杂。无论使用何种技术来实现这些功能,这一点都是正确的。

过去 20 年来,设计和实现复杂系统的挑战并没有消失。如果说有什么不同的话,那就是,由于分布式计算和网络集成的日益普及,以及在云中使用网络和移动应用程序对传统商业模式的持续颠覆,它们可能变得更加明显。

DDD 和 EIP 作者谈论变化
"埃里克-埃文斯(Eric Evans)说:"DDD 的技术水平肯定比二十年前要高。

"我认为最大的变化是系统架构在这段时间内发生的巨大变化。他补充说:"现在,我们通常可以在微服务中创建更小、更专业的模型。

此外,Hohpe 还指出:"构建分布式系统的许多基本挑战,如异步、惰性、最终一致性等,依然存在。

然而,变化的是,如今几乎所有构建的系统,尤其是在云平台之上构建的系统,都是分布式的,Hohpe 说。

在过去的 20 年里,有一件事很明显地发生了,那就是 DDD 已被采纳为降低微服务设计复杂性的默认方法,而 EIP 则被采纳为降低实现这些设计复杂性的默认方法(尤其是针对事件或 Hohpe 坚持称之为 "消息 "的设计)。

埃文斯指出:消息在架构中无处不在,这使得使用事件建模更加自然。"定义消息含义的需求增加了语言在系统中的可见性。当前的技术平台比 20 年前的技术平台更支持 DDD。它仍然非常困难!我认为它将永远如此。但意外的复杂性似乎有所降低。

使用 DDD 和 EIP 的一些示例
举例来说,假设您正在将整体应用程序重新设计为云原生微服务,以处理季节性工作负载,就像我们在 2013 年为花旗支付处理系统所做的那样。

  • 首先,您将使用 DDD 语言来识别您的业务领域,识别这些领域的微服务,并确定它们的粒度以及在何处绘制接口边界。
  • 然后,您将使用EIP设计它们之间的连接,考虑耦合和操作方面(例如高负载下的延迟或行为),并决定何时使用请求/响应以及何时使用异步消息传递。

在去年的 HPTS 会议上,  Tesla 的软件工程师 Colin Breck描述了他们对事件驱动的微服务模式的实现。在Tesla应用程序中,某些事件由汽车遥测触发,并使用消息传递到存储和检索这些事件以进行分析的微服务,例如为发生低电量事件的汽车查找最近的开放充电站。

在事件驱动模式的另一个例子中,沃尔玛用一个系统替换了基于 RPC 的库存查询系统,只要特定商品的可用库存发生变化,该系统就会将事件传播到可查询的公共数据存储。

DDD和EIP的下一步是什么?
到目前为止,这两本书都不需要更新,尽管作者在他们的网站上添加了参考材料和更新的实现示例(对于 DDD,请参阅 领域语言 ,对于 EIP,请参阅 Gregor[url=https://www.enterpriseintegrationpatterns.com/ramblings.html]的 Ramblings[/url] 和 The Architect Elevator)。

我们对领域进行建模的方式发生了一些重要的变化。最明显的是,领域事件是领域模型的一流成员。函数式编程成为主流也有所帮助,它解放了人们对模型的思考方式

事实上,对于模型应该是什么样子或应该是什么,人们存在一些先入为主的观念。埃文斯的书旨在提供原理的说明或示例,而不是事物本身

这种先入之见可能会 导致思维短路。

给 DDD 和EIP读者的建议
埃文斯说,要真正让领域建模有价值,你必须心胸开阔。在进行项目时,埃文斯指出,他考虑的是上下文边界在哪里,而不是它们应该具有哪些实体或值对象。

问题的关键在于,要找到领域中重要而又令人头疼的部分。找一些具体的例子来说明为什么它很难。埃文斯说:"用语言进行实验,直到你能清晰简洁地讲述这些例子。"这就是我们语言的开端,也是我们模型的第一张草图。这些模型可能与我书中的例子(和模式)完全不同。这些对我来说很有趣

与此同时,图表符号已经流行起来,并被普遍用于记录集成解决方案。但图表并不是解决方案;软件架构图只是一种表述。

(banq注:DDD是从上到下的设计实现,而EIP是对从下而上涌现的系统进行衔接,两者适用的上下文完全不同,相同的可能是领域事件这个术语,关键问题是人们从上而下DDD设计实现时,对上下文边界认识不够,导致系统成型后,不得不用EIP企业集成模式实现集成,如果说DDD是建筑师图纸设计,那么EIP可能是物业维修工,两者都是都建筑进行操作,但是需要的上下文时机不同。)