Graph + AI 中国峰会火热报名中,点击探索图分析更多可能! 了解详情
写点什么

领域驱动设计入门

作者:Jannik Wemp

2021 年 8 月 23 日

领域驱动设计入门

领域驱动设计(DDD)是由 Eric Evans 发明的一个概念。他在 2004 年出版的《领域驱动设计》一书(即”大蓝皮书“)中探讨了这个概念。我将概要地介绍下 DDD 的方方面面。本文将探讨 DDD“为什么?”和“是什么?”。在这里,我不会深入探讨具体的主题。不过,我会说明重要术语的定义。


领域驱动设计(DDD)是由 Eric Evans 发明的一个概念。他在 2004 年出版的《领域驱动设计》一书(即”大蓝皮书“)中探讨了这个概念。


那么在 DDD 上下文中,领域是什么?


领域是知识、影响或活动的范围。用户应用程序的主题域即软件的领域。


我将概要地介绍下 DDD 的方方面面。本文将探讨 DDD“为什么?”和“是什么?”。在这里,我不会深入探讨具体的主题。不过,我会说明重要术语的定义,就像上面的“领域”。你会发现,共享词汇也是 DDD 本身的一部分。


首先,你要问自己,这些概念是否仍然有效?


DDD 的意义


DDD 不是一种特定的技术,它是一个概念。许多现代概念都直接使用 DDD。下面这段话出自 Sam Newman《微服务设计》一书的第一页。


Eric Evans 的《领域驱动设计》一书帮助我们理解了用代码呈现真实世界的重要性,并且告诉我们如何更好地进行系统建模。


此外,IBM Garage 事件驱动参考架构有一章专门介绍 DDD 方法。


至于 DDD 的意义,可以说时至今日,它确实非常有效。说完了最新的情况,让我们继续探讨 “为什么?”和 “是什么?”


为什么会有 DDD


DDD 不是一种特定的技术,它是一个概念。许多现代概念都直接使用 DDD。下面这段话出自 Sam Newman《微服务设计》一书的第一页。


为什么会需要像 DDD 这样的东西?Eric Evans 在其著作的副标题中提供了一条很好的线索:


攻克软件核心的复杂性


通常情况下,软件项目的主要复杂性在于领域本身。你无法改变领域的复杂性。你可以试试告诉你的银行客户,你将专注于支付,而放弃贷款业务,因为它太复杂了。


此外,我们不是为了开发软件而开发软件。我们是为了解决问题以及做些改进:


软件的核心是为用户解决领域相关问题的能力。其他所有功能,虽然也很重要,但都是服务于这一基本目的。


DDD 是什么


微服务的关键特征之一就是其松散的耦合,而这一特征则允许它们单独进行开发、部署、访问控制和扩展。


那么 DDD 是什么?DDD 无法用一两个句子定义。它是一种开发解决多个问题的复杂软件的方法:


  1. 关注领域的核心复杂性和机会;

  2. 领域专家和软件专家合作探索模型;

  3. 在有界上下文中说一种通用语言。


(注意正文中的绿色词汇。这些是 DDD 中特有的术语,我会给它们下个定义,就像给领域下定义一样。)


这三点是对 DDD 非常高度的概括。接下来,我会一个一个地介绍。


关注领域


关注领域的核心复杂性和机会。


这一点我就不过多介绍了。根本的东西我在上面“为什么”这一部分里都已经说明了。软件是没有自我目的的。


不要把这点和“关注业务”弄混了。核心复杂性和机会与我们所说的“业务”并不是一回事。想一下 Twitter。在它的功能中,互相关注等功能并非主要的复杂性所在。主要的复杂性更多的可能还是来自扩展平台。


探索模型


领域专家和软件专家合作探究模型。


模型是应对上述复杂性的一种方法。但首先,我们要弄清楚模型是什么?


在 DDD 上下文中,模型是什么?


描述领域部分方面的一系列抽象,可以用于解决与该领域相关的问题。


另一种来自 Eric Evans 的描述:


模型是一种简化。它是对现实的解释,它将有助于解决现有问题的重要方面抽象出来,而忽略掉不相干的细节。


我觉得有必要明确下它不是什么:它不是一张图(因此也不是实体关系图(ERD),虽然 DDD 也使用实体这个术语)。图只是帮我们就模型进行交流。在 DDD 的语境下,你会看到许多图。没有什么唯一的建模专用语言。最常用的是一些类似 UML 的图,或者仅仅是一幅手绘草图。重要的不是图,而是图背后的概念。


选择“探索(explore)”而不是像“写下”这样的词,是有其用意的。要获得一个模型,需要经过一个迭代过程。建模这样的事不可能一次性完成。领域里会有新的洞察,新的或变化的问题,诸如此类。这是一个持续探索的过程。


模型举例


考虑下平常的世界地图(有点像一张图)。标准世界地图显示的是墨卡托投影。人们都知道,地图不是为了说明不同国家的大小或其他类似的东西。它是专门为海上航行而制作的。在地图上的两点之间画一条线,借助指南针就可以知道如何航行了。


下图显示了地图背后的东西,即具体的模型:



Eric Evans 在 2019 年的会议演讲中使用的这个例子很不错。它说明了模型与当前的问题直接相关。


有个模型并不能让你获得任何优势。优势并非因为有模型。优势是你因为有一个模型,可以非常好的匹配你正在设法解决的一组特定问题。


对比开头的句子,这里少了一个非常重要的部分:“领域专家和软件专家合作“。模型必须合作探索。不是单由领域专家创建模型,也不是单由开发人员拿 ERD 当模型叫卖。Eric Evans 将合作探索模型的过程称为“知识研磨(Knowledge Crunching)”。


在本节的最后,让我们看一个非常重要的观点。Eric Evans 的下面两段话是这一观点的最佳表述。


本书的主旨是,实施、设计和团队沟通应该在一个模型里。不同的用途采用不同的模型会存在隐患。


如果编写代码的人觉得自己不负责模型,或者不理解如何在应用程序开发中运用模型,那么模型就和软件没关系了。如果开发人员没有意识到修改代码会改变模型,那么他们的重构会弱化而非强化模型。


本节要点:代码和模型直接相关。


说一种通用语言


在有界上下文中说一种通用语言。


在 DDD 上下文中,通用语言指的是什么?


一种围绕领域模型构造的语言,供所有团队在有界上下文中使用,将团队的所有活动与软件联系起来。


还有一个有必要定义的术语是:有界上下文。


上下文:单词或语句在其中出现的、可以决定其意思的环境。模型的语句只能在上下文中进行理解。


有界上下文:对边界(通常是一个子系统或特定团队的工作)的描述,特定模型在其中定义,同时也是模型的适用范围。


(至此,我们已经介绍了本文所需的所有定义。)


值得注意的是,“通用”语言并不是适用于整个系统的通用。它主要是用于代码、口语、图表等方面。这也是为什么要说“在有界上下文内”。该语言将在你明确定义的边界内适用。它定义的不是跨边界(如整个公司)的术语。举例来说,这会让营销或仓储上下文的文章看起来大相径庭,甚至是在仓储上下文的不同部分也是如此。


(你可能已经注意到,我在每个定义里都加了“在 DDD 上下文中“。这就是原因。)


用我自己的话来说:通用语言是特定领域中与模型直接关联的公共语言,在定义好的边界内可以随处使用。“与模型直接关联”是说语言的变化也会直接关系到模型的变化。事实上,模型应该使用领域专家已经在使用的术语创建。


[...] 语言的更改将被看成是领域模型的更改,团队得相应地更新类图,重命名代码中的类和方法[...]模型是语言的支柱。[...] 在图表、写作,特别是口语中使用同样的语言。


现在,我们已经清楚了术语的含义,但为什么这很重要呢?关于这一点,书中有这么一段话:


在一个没有公共语言的项目里,开发人员得给领域专家做翻译。领域专家要在开发人员之间做翻译,同时还要给其他领域专家做翻译。甚至开发人员之间也需要翻译。


你一定遇到过这样的情况,开发人员不知道领域专家在说什么,或者更糟糕,你觉得自己知道,但他/她说的其实是其他东西。反之亦然。


对于使用的专门术语,要使团队养成询问其含义的习惯。团队要在所有的沟通活动中不断地练习使用通用语言。如果领域专家正在谈论的、属于某个特定领域的概念在模型中没有体现,那么这个模型可能不完善。


通用语言会使得代码与实际的领域更贴合。这不仅是说代码可以体现实际的领域,而且还有许多其他方面的好处。考虑下代码的可维护性。如果后续有开发人员回过头来查看代码,其中使用了领域术语。确实,领域专家了解用到的术语,但那并不是开发人员定义的类名。


更多概念


上面的内容是对 DDD 一个高度概括的介绍。无疑,它还有许多其他的概念。



上图是 DDD 中不同概念的一个总览。如你所见,我只介绍了其中的一小部分。我接下来会写一篇文章介绍实体、值对象和聚合的概念。但本文足以帮你了解 DDD 是干什么的。


总结


DDD 仍然是你工具箱中的一个重要概念。它已经影响了许多其他的领域可以看下JPA规范的JavaDoc

,并且还会继续影响它们。


解决领域问题是软件开发的全部内容。那是我们需要面对的复杂性。但是,运用 DDD 可以让我们的工作变得更轻松。


希望您喜欢这篇文章。欢迎反馈。您可以在TwitterLinkedIn上联系我:


相关资料


当然,最主要的资料是《领域驱动设计》一书


Eric Evans 在网上免费提供的领域设计驱动参考


IBM Garage事件驱动参考架构也包含有关 DDD 的信息


我很喜欢Eric Evans在DDD欧洲2019大会上的演讲


当然,YouTube 上还有其他许多不错的演讲。


原文链接:


https://blog.jannikwempe.com/domain-driven-design-introduction

2021 年 8 月 23 日 16:244760
用户头像
万佳 InfoQ编辑

发布了 623 篇内容, 共 237.4 次阅读, 收获喜欢 1597 次。

关注

评论

发布
暂无评论
  • 基于 DDD、CQRS、微服务和事件溯源构建系统

    对于构建系统来说,模块化是至关重要的,但实现模块化需要应对一些反模块化的做法。

  • 领域驱动设计精简版

    如何设计能深刻反映业务领域的领域模型?领域模型设计的未来发展方向是什么?……本书是Eric Evans的《领域驱动模型》一书的精简版,让你在短时间内理解领域驱动设计的内容。这本书没有介绍任何新的概念,它只是概要总结了领域驱动设计的本质,抽取了Eric Evans原书中关于这一主题的大部分内容,以及其他相关资料。这本书可以让你快速了解领域驱动设计的基础知识,但不能替代Eric书中提供的大量事例和案例研究或者Jimmy书中提供的动手事例等。

  • 02|统一语言是必要的吗?

    虽然在理想中,我们希望直接使用模型作为统一语言。但从实际出发,直接使用模型的效果并不好。所以我们仍然需要统一语言。

    2021 年 6 月 26 日

  • 捕获 - 嵌入 - 防护:领域驱动设计的指导原则

    在使用DDD核心理念和实践作为软件设计和开发的指导方针时,可以概括为三个原则:捕获、嵌入、防护。这是Steven A. Lowe在今年的DDD交流大会上演讲时提出的。捕获领域模型。将模型嵌入代码。保护领域模型免受其他领域的侵蚀。

  • 如何设计一款大型 Laravel 应用程序的架构(下)?

    本文是系列文章第二篇,主要讨论在一个传统的Laravel app中加入事件溯源。

  • Eric Evans:领域驱动设计有利于软件开发吗?

    Eric Evans最近在伦敦举办的DDD eXchange大会上做了一次主题演讲。他在演讲中指出,过去的几年中,对领域驱动设计(DDD)的兴趣有所增加。他认为,我们正处在一个开发人员更在乎设计的时代,部分原因是因为我们更多的工作在分布式系统上,而其中模型具有较高的价值。

  • Eric Evans:DDD 不是为完美主义者而生

    追寻完美设计是从一开始就伴随着领域驱动设计(DDD)的常见问题,但DDD不是为完美主义者而生的。最近在阿姆斯特丹的DDD欧洲会议上,Eric Evans在其演讲中指出,为了停止这种追求,你需要对如何创建设计良好但并不完美的软件有一些概念。

  • 介绍行为驱动开发

    行为驱动开发(Behaviour-Driven Development (BDD)有助于克服开发人员对构建产品需求的理解与业务人员对需求引起的技术困难理解之间的差距。原因是改善两组之间的沟通,Alistair Stead 和 Konstantin Kudryashov在他们的BDD入门指南中做了解释。

  • 你的代码为谁而写?

    代码是程序员与机器沟通的桥梁,写好代码是每个程序员的追求,一个专业程序员,追求的不仅是实现功能,还要追求代码可维护。

    2019 年 2 月 20 日

  • 开篇词|为什么你需要学习业务建模?

    业务建模首先是一个定义问题的方法,其次才是解决问题的方法。通过定义问题,甚至可以把解决方案的复杂度直接降低几个数量级。

    2021 年 6 月 23 日

  • 基于上下文图的策略性领域驱动开发

    当应用程序逐渐变得庞大和复杂后,很多面向对象建模的方法都达不到非常好的可伸缩性。上下文图是一种通用目的的技术,作为领域驱动开发大家族的一名成员,它帮助架构师和开发人员管理他们在软件开发项目中不得不面对的形形色色的复杂性。在这篇文章中,作者Alberto Brandolini探讨了界限上下文,以及如何在构建上下文图时应用它们,来支持软件开发项目中的关键决策。

  • 可复用架构案例(一):如何设计一个基础服务?

    对于落地一个共享服务来说,服务边界的划分和功能的抽象设计是核心。今天我就以案例说明如何从头开始落地一个典型的共享服务。

    2020 年 3 月 9 日

  • 领域驱动设计 101- 上下文与持续集成

    前面我们已经讨论了领域、模型、通用语言以及分层设计这些领域驱动设计中的基础概念。现在,让我们来认识领域驱动设计中战略设计相关的概念。

    2021 年 4 月 19 日

  • 抽奖|《DDD 实战课》沉淀成书了,感谢有你!

    留言区参与互动,将有机会获得作者签名书一本。

    2020 年 11 月 13 日

  • BDD 是什么东西?

    当 JUnit 带来的自动化测试框架风潮迅速席卷了整个开发者社区,成了行业的事实标准,就开始有人基于测试框架的模型进行延伸了。各种探索中,最有影响力的就是 BDD。

    2021 年 9 月 13 日

  • Eric Evans:领域驱动设计的实践

    Eric Evans在最近于阿姆斯特丹举行的DDD Europe 2018上做了主题演讲,他认为构建软件时,很重要的一点就是不断地探索和练习。他非常青睐领域驱动设计(DDD)中的策略模式,但是他发现真正有意思的是接受一个困难的领域,按照不同的方式进行推导分析,打破窠臼,尝试寻找新的理念。

  • 使用反应式领域驱动设计来解决不确定性

    Vaughn Vernon撰写了几本关于DDD和反应式消息传递模式的书,并发现分布式系统的本质意味着你必须处理不确定性。如何响应丢失的消息或重复收到的消息应该是一种业务决策,因此必须是领域模型的一部分。

  • DDD 被高估了吗?

    领域驱动设计(DDD)最近越来越受欢迎,但它并非“银弹”。

  • MDE 为何错失良机?

    每个月都会有更多关于编程语言的活动,也会有更多人对编程语言感兴趣。Jean Bezivin上周在SPLASH大会上提出这样的观点,人们已经对MDE的不感兴趣了。他对这种状况阐述了自己的分析结果。

  • 从头开始实现领域驱动设计

    领域描述业务,在领域驱动设计(DDD)中,领域是应用程序中最重要的组成部分。Andras Nemes在关于用领域驱动设计原则构建Web服务的系列博客的开篇中就提到,他的目标不是覆盖DDD的方方面面和所有细节,而是希望即便刚刚接触DDD的开发人员也能从中受益。

发现更多内容

还在手动写数据库文档吗?试试这个工具,划水干活儿两不误!

我爱娃哈哈😍

数据库 文档生成

一个正确的编程思维

程序员吴师兄

28天写作

要想软件“一想之美”,UI测试少不了

华为云开发者社区

软件 测试 华为云

Spark HistoryServer日志解析&清理异常

笨小康

大数据 spark hdfs

Kube-OVN v 0.7.0 发布,IPAM、子网和安全功能增强

York

灵雀云 Kubernetes k8s Kube-OVN

ETL都没弄懂,谈什么大数据 ?我用一分钟给你整明白

智分析

ETL

云算力矿机租赁挖矿APP系统开发|云算力矿机租赁挖矿软件开发

开發I852946OIIO

系统开发

Hive的调优你都知道那些?

大数据老哥

大数据 hadoop hive

SpringCloud从入门到精通02---支付模块01

Felix

杜绝标题党,好的标题是成功的99%

xcbeyond

方法论 28天写作 写作技巧

如果你听说过 Elastic Certified Engineer

escray

七日更 28天写作 死磕Elasticsearch 60天通过Elastic认证考试

从七日更,到28天写作挑战,我无法拒绝的原因

梁龙先森

前端 编程语言 28天写作

volatile 关键字精讲

伯阳

Java volatile 关键字 后端开发 多线程与高并发

技术实录 | 灵雀云基于 OVN 的 Kubernetes 网络架构解析

York

灵雀云 Kubernetes k8s Kube-OVN

灵雀云Kube-OVN:基于OVN的开源Kubernetes网络实践

York

灵雀云 Kubernetes k8s Kube-OVN

大作业一:架构设计方案评审

Nick~毓

软件测试--缺陷报告

测试人生路

软件测试

价值 - 价值的底色(一)

石云升

读书笔记 投资 28天写作 价值

Kube-OVN 0.5.0 发布,支持 NetworkPolicy、用户自定义网卡和MTU

York

灵雀云 Kubernetes k8s Kube-OVN

VUE项目性能优化实践——通过懒加载提升页面响应速度

Geek_Willie

Vue

Kube-OVN 0.6.0 发布,支持 IPv6、流量镜像及更多功能

York

灵雀云 Kubernetes k8s Kube-OVN

文档驱动开发模式在 AIMS 中的应用与实践

华为云开发者社区

Web 代码 API 文档

软件界旷世之架:测试驱动开发(TDD)之争

华为云开发者社区

软件 测试 TDD 代码 devcloud

SpringCloud从入门到精通01---父项目创建

Felix

SpringCloud Eureka 高可用架构

开始的开始-可能是最早提交的28天写作活动作品

石君

28天写作

边缘计算安全技术研究

华为云原生团队

云计算 大数据 云原生 边缘计算 华为云

代码也能“杀”虫:此虫,真虫非Bug也

华为云开发者社区

代码 华为云 modelarts

Java中定时器Timer致命缺点(附学习方法)

叫练

学习 定时任务 多线程 定时器 技术学习

新思科技网络安全研究中心发现Bouncy Castle中的漏洞

InfoQ_434670063458

新思科技 Bouncy Castle

再谈自研开源Kube-OVN, 设计思路及实现原理

York

灵雀云 Kubernetes k8s Kube-OVN

Yarn RM写ZNode超数据量限制bug修复

笨小康

大数据 zookeeper YARN

聊一下 Mesh 数据平面 Sidecar 与 Service 通信的那些事儿

聊一下 Mesh 数据平面 Sidecar 与 Service 通信的那些事儿

领域驱动设计入门-InfoQ