深入实践DDD:以DSL驱动复杂软件开发pdf下载pdf下载

深入实践DDD:以DSL驱动复杂软件开发百度网盘pdf下载

作者:
简介:本篇主要提供深入实践DDD:以DSL驱动复杂软件开发pdf下载
出版社:机械工业出版社自营官方旗舰店
出版时间:2021-04
pdf下载价格:9.00¥


预览


内容介绍

编辑推荐

适读人群 :1. 产品经理与系统分析师。产品经理不应该仅仅关注软件的界面原型、用户体验,产品经理需要保证团队所开发的是 “正确的软件”。正确的软件应该逻辑自洽,功能处处传达出那个

1)领域驱动设计里程碑之作,资深技术专家兼技术管理者二十年工作经验结晶

(2)深度解读DDD思想,揭示使用 DSL实现DDD快速落地的方法与技巧,缓解复杂软件开发之痛

内容简介

本书是拥有二十年商业软件开发经验及十年技术管理经验的资深技术专家呕心沥血之作,也是目前市场上少有的阐述如何通过使用领域专用语言(DSL)实现领域驱动设计(DDD)的图书。
书中首先带领读者重温DDD在战术设计层面及战略设计层面上的部分重要概念,并简要介绍了自DDD社区兴起的一些软件架构模式。然后阐述如何设计一门DDD原生的DSL,包括这个DSL的规范支持哪些特性、如何帮助团队描述领域模型的方方面面、这些特性的选择基于何种考量等。然后在此基础上详细讲解了如何使用技术工具将描述领域模型的DSL文档直接转化为可以工作的软件代码,在这个过程中结合诸多来自商业软件开发工作中的真实案例,展示并分析了大量的关键代码,让读者可以深入地了解制造那些基于DSL的DDD技术工具的秘密。之后讲述了一些建模案例,并探讨了一些与DDD相关的其他话题,对读者开拓技术思维、更深刻地理解DDD有所助益。

作者简介

杨捷锋,曾就职于南开戈德集团、普天集团、通路快建等公司。曾作为独立技术顾问为海尔集团、沈阳飞机工业集团、上广电NEC、天马微电子等企业提供软件开发与技术咨询服务。目前在一家电商创业公司担任技术负责人。有多个大型企业应用软件的分析建模经验,以及大型开发框架(ORM、IoC等)的架构经验。多年来一直未脱离软件开发一线工作,对软件系统分析、数据建模、领域驱动设计、项目管理略有心得。

精彩书评

开发软件困难的部分其实是建立对软件所服务的领域的认知,即“领域建模”。那么应该构建何种风格的领域模型以及如何描述所构造的模型呢?杨捷锋向我们强烈推荐DDD以及DSL——以“领域驱动设计”的方法构造 DDD 风格的领域模型,并以DSL来描述它们。作者以近20年的编码经验练就的深厚功力,在书中写下DDD实践的思考及建议,十分精彩,令人击节。

—— 郝培强(Tinyfool)  英语轻松读创始人


技术的本质是为了业务创新或者解决业务中的各种问题。领域驱动设计(DDD)是架构设计中的经典思想,经典不会过时。杨捷锋的DSL实践给我们带来了DDD领域的更多经验与思考。
—— 杨卫华(Tim Yang)  Westar区块链实验室创始人、中国计算机学会TF架构SIG主席


传统企业的数字化不仅需要推动互联网发展的高并发、大数据等新技术,更需要构建领域模型,以支持复杂的企业业务的持续演进。如何才能实现?良方是DDD。但是,技术人员没有一定的经验,运用DDD时很容易犯错误。本书从道、术、工具等多个层次阐述DDD。需要举例说明时,作者不满足于使用简单的例子,而是拿出工作中碰到的经典案例来讲解,更有结合DDD对软件SaaS化及PaaS化的思考。本书值得借鉴与研读。
—— 刘建  蓝图移动首席架构师、前蓝信技术合伙人


为了避免业务突变而燃尽利润,我们需要构建对领域的深度认知模型。但模型描述标准化、代码生成等难题多年来横亘在DDD前进的道路上。Eric Evans早就说过,DSL会是DDD的下一大步,现在我们终于有了DDDML!基于DDDML的解决方案已经在电商行业实践,现在更剑指构建云端FaaS平台的“小目标”——具有业务价值的代码应该用简单的函数来写。诸多细分领域的DSL(如BPMN 2.0)已然大获成功,相信DDDML亦当如此。
—— 胡天成  原PFU(富士通集团)技术顾问


领域驱动设计是个美妙的愿景。长期以来,虽有不少技术管理者对各种先进的概念和方法论充满激情,但像作者这样多年在工作中坚持实践领域驱动设计的,并不多见。作者早年主要为海尔、宝洁、沈飞、朗讯等传统企业提供技术服务,近几年又投身于互联网行业,经验丰富。本书不囿于管理者的视角,更从工程师的角度直指领域驱动设计落地的关键,书中充满操作性极强的建议,直至代码级的剖析讲解,值得拥有。
—— 杨彬  海贝易通董事长、前朗讯研发总监


目录

【第一部分 概念】

第1章 DDD 的关键概念 2

1.1 自顶而下、逐步求精 3

1.1.1 DDD开创全新分析流派 3

1.1.2 什么是软件的核心复杂性 4

1.2 什么是领域模型 4

1.3 战术层面的关键概念 6

1.3.1 实体 6

1.3.2 值对象 6

1.3.3 聚合与聚合根、聚合内部实体 7

1.3.4 聚合的整体与局部 9

1.3.5 聚合是数据修改的单元 9

1.3.6 聚合分析是“拆分”的基础 10

1.3.7 服务 12

1.4 战略层面的关键概念 13

1.4.1 限界上下文 13

1.4.2 限界上下文与微服务 14

1.4.3 防腐层 15

1.4.4 统一语言 18

1.5 ER 模型、OO模型和关系模型 19

1.6 概念建模与模型范式 21

第2章 其他DDD相关概念 22

2.1 领域 ID 22

2.1.1 自然键与代理键 23

2.1.2 DDD 实体的 ID 需要被最终用户看到 23

2.1.3 什么时候使用代理键 24

2.2 ID、Local ID 与 Global ID 26

2.3 命令、事件与状态 27

第3章 CQRS 与 Event Sourcing 29

3.1 命令查询职责分离 29

3.2 事件溯源 32

3.3 From-Thru 模式 33

3.3.1 示例:ProductPrice 33

3.3.2 示例:PartyRelationship 35

3.4 CQRS、ES 与流处理 36


【第二部分 设计】

第4章 DDD 的 DSL是什么 40

4.1 为什么 DDD 需要 DSL 41

4.1.1 为什么实现 DDD 那么难 41

4.1.2 搞定 DDD 的“锤子”在哪里 42

4.2 需要什么样的 DSL 43

4.2.1 在“信仰”上保持中立 44

4.2.2 DDD 原生 45

4.2.3 在复杂和简单中平衡 46

4.2.4 通过 DSL 重塑软件开发过程 48

4.3 DDDML——DDD 的 DSL 48

4.3.1 DDDML 的词汇表 49

4.3.2 DDDML 的 Schema 51

4.4 DDDML 示例:Car 52

4.4.1 “对象”的名称在哪里 55

4.4.2 使用两种命名风格:camelCase 与 PascalCase 55

4.4.3 为何引入关键字 itemType 56

第5章 限界上下文 57

5.1 DDDML 文档的根结点下有什么 57

5.2 限界上下文的配置 59

5.3 名称空间 62

5.3.1 再谈 PascalCase 命名风格 62

5.3.2 注意两个字母的首字母缩写词 63

5.4 关于模块 64

第6章 值对象 67

6.1 领域基础类型 68

6.1.1 例子:从 OFBiz 借鉴过来的类型系统 70

6.1.2 例子:任务的触发器 73

6.2 数据值对象 75

6.3 枚举对象 76

第7章 聚合与实体 79

7.1 用同一个结点描述聚合及聚合根 79

7.2 实体之间只有一种基本关系 82

7.3 关于实体的 ID 85

7.4 不变的实体 89

7.5 动态对象 90

7.6  继承与多态 92

7.6.1 使用关键字 inheritedFrom 94

7.6.2 超对象 95

7.7 引用 97

7.7.1 定义实体的引用 97

7.7.2 属性的类型与引用类型 101

7.8 基本属性与派生属性 102

7.8.1 类型为实体集合的派生属性 103

7.8.2 类型为值对象的派生属性 106

7.9 约束 107

7.9.1 在实体层面的约束 107

7.9.2 在属性层面的约束 109

7.10 提供扩展点 110

第8章 超越数据模型 112

8.1 实体的方法 112

8.1.1 聚合根的方法 115

8.1.2 非聚合根实体的方法 116

8.1.3 属性的命令 117

8.1.4 命令 ID 与请求者 ID 119

8.2 记录业务逻辑 119

8.2.1 关于 accountingQuantityTypes 120

8.2.2 关于 derivationLogic 120

8.2.3 关于 filter 121

8.2.4 使用关键字referenceFilter 121

8.2.5 业务逻辑代码中的变量 122

8.2.6 说说区块链 123

8.3 领域服务 123

8.4 在方法定义中使用关键字 inheritedFrom 125

8.5 方法的安全性 126

第9章 模式 128

9.1 账务模式 128

9.2 状态机模式 132

9.3 树结构模式 137

9.3.1 简单的树 137

9.3.2 使用关键字structureType 138

9.3.3 使用关键字structureTypeFilter 139


【第三部分 实践】

第10章 处理限界上下文与值对象 142

10.1 项目文件 143

10.2 处理值对象 144

10.2.1 一个需要处理的数据值对象示例 145

10.2.2 使用 Hibernate 存储数据值对象 146

10.2.3 处理值对象的集合 149

10.2.4 在 URL 中使用数据值对象 151

10.2.5 处理领域基础类型 153

第11章 处理聚合与实体 161

11.1 生成聚合的代码 162

11.1.1 接口 163

11.1.2 代码中的命名问题 178

11.1.3 接口的实现 179

11.1.4 事件存储与持久化 207

11.1.5 使用 Validation 框架 218

11.1.6 保证静态方法与模型同步更新 220

11.1.7 不使用事件溯源 222

11.2 Override 聚合对象的方法 223

11.3 处理继承 225

11.3.1 TPCH 226

11.3.2 TPCC 227

11.3.3 TPS 228

11.4 处理模式 229

11.4.1 处理账务模式 229

11.4.2 处理状态机模式 234

第12章 处理领域服务 238

12.1 处理数据的一致性 239

12.1.1 使用数据库事务实现一致性 240

12.1.2 使用 Saga 实现最终一致性 241

12.2 发布与处理领域事件 243

12.2.1 编写 DDDML 文档 243

12.2.2 生成的事件发布代码 245

12.2.3 编写生产端聚合的业务逻辑 253

12.2.4 实现消费端领域事件的处理 254

12.3 支持基于编制的 Saga 255

12.3.1 编写 DDDML 文档 255

12.3.2 生成的 Saga 命令处理代码 261

12.3.3 需要我们编写的 Saga 代码 268

12.3.4 需要我们实现的实体方法 273

第13章 RESTful API 276

13.1 RESTful API 的最佳实践 276

13.1.1 没有必要绞尽脑汁地寻找名词 277

13.1.2 尽可能使用 HTTP作为封包 277

13.1.3 异常处理 279

13.2 聚合的 RESTful API 280

13.2.1 GET 280

13.2.2 PUT 291

13.2.3 PATCH 293

13.2.4 DELETE 295

13.2.5 POST 295

13.2.6 事件溯源 API 296

13.2.7 树的查询接口 297

13.3 服务的 RESTful API 297

13.4 身份与访问管理 299

13.4.1 获取 OAuth 2.0 Bearer Token 299

13.4.2 在资源服务器上处理授权 301

13.5 生成 Client SDK 302

13.5.1 创建聚合实例 303

13.5.2 更新聚合实例 304

13.5.3 使用 Retrofit2 306

第14章 直达 UI 308

14.1 两条路线的斗争 309

14.1.1 前端“知道”领域模型 309

14.1.2 前端“只知道”RESTful API 312

14.2 生成 Admin UI 312

14.2.1 使用 referenceFilter 313

14.2.2 展示派生的实体集合属性 315

14.2.3 使用属性层面的约束 316

14.2.4 使用 UI 层元数据 317

14.2.5 构建更实时的应用 318


【第四部分 建模漫谈与 DDD 随想】

第15章 找回敏捷的软件设计 322

15.1 重构不是万能灵药 323

15.2 数据建模示例:订单的装运与支付 324

15.2.1 订单与订单行项 325

15.2.2 订单与订单装运组 327

15.2.3 订单与装运单 328

15.2.4 订单的项目发货 329

15.2.5 订单的支付 330

15.3 中台是一个轮回 332

15.4 实例化需求与行为驱动测试 334

15.4.1  什么是实例化需求 334

15.4.2 BDD 工具 335

15.4.3 BDD 工具应与 DDD 相得益彰 336

15.4.4 不要在验收测试中使用固件数据 336

15.4.5 制造“制造数据”的工具 337

15.5 要领域模型驱动,不要 UI 驱动 345

15.6 不要用“我”的视角设计核心模型 346

15.6.1 让 User 消失 347

15.6.2 认识一下 Party 348

15.7 我们想要的敏捷设计 350

第16章 说说 SaaS 351

16.1 何为 SaaS 351

16.2 多租户技术 352

16.3 构建成功的 SaaS 有何难 353

16.3.1 多租户系统的构建成本 353

16.3.2 难以满足的定制化需求 353

16.3.3 负重前行的传统软件公司 355

16.4 SaaS 需要 DDD 355

第17章 更好的“锤子” 356

17.1 我们制作的一个 DDDML GUI 工具 357

17.1.1 给领域建模提供起点 357

17.1.2 创建新的限界上下文 358

17.1.3 从 OFBiz 中“借鉴”数据模型 359

17.1.4 构建项目并运行应用 361

17.1.5 使用 HTTP PUT 方法创建实体 362

17.1.6 给聚合增加方法 363

17.1.7 生成限界上下文的Demo Admin UI 368

17.1.8 让不同层级的开发人员各尽其能 369

17.2 以统一语言建模 370

附录 DDDML 示例与缩写表 373

前言/序言

【为什么要写这本书】

2004 年,DDD(领域驱动设计)这一软件开发的方法与愿景经由建模专家 Eric Evans 的经典著作Domain-Driven Design: Tackling Complexity in the Heart of Software 正式面世,当即获得了广泛关注和高度评价。16 年过去了,我在网上看到越来越多关于 DDD的文章和讨论。为什么我们现在还不停地讨论 DDD?为什么DDD仍然如此重要?

在商业组织中,主张“技术为业务服务”的企业总可以在理论上立于不败之地。诚然,DDD主张在软件项目中把领域本身作为关注的焦点(换句话说就是技术人员要懂业务)符合这种思想,但真正难能可贵的是,DDD提供了切实可行的应对软件核心复杂性的方法。

实践证明,DDD 提出的方法不仅行之有效,而且历久弥新。关于这一点,我想从当今 IT 业界的热词“云原生”“中台”“产业互联网”说起。

什么是云原生?云原生计算基金会(Cloud Native Computing Foundation,CNCF)对云原生的定义是:

云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式 API。

这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段,云原生技术使工程师能够轻松地对系统做出频繁和可预测的重大变更。

而阿里云发布的《云原生架构白皮书》 对云原生架构的定义是:

从技术的角度看,云原生架构是基于云原生技术的一组架构原则和设计模式的集合,旨在将云应用中的非业务代码部分进行最大化剥离,从而让云设施接管应用中原有的大量非功能特性(如弹性、韧性、安全、 可观测性、灰度等),使业务不再有非功能性业务中断困扰的同时,具备轻量、敏捷、高度自动化的特点。

看了这些定义,你是否还是觉得迷惑?打开CNCF的“landscape”页面——里面有很多的项目和成员,难怪有人说云原生是一个“营销词语”。在这个页面中,在 Members(成员)这个标签页的左边,Serverless 独占了一个标签页,十分显眼。

广泛认同的Serverless 架构是指这样的应用设计:与第三方的后端即服务(Backend as a Service,BaaS)交互;在函数即服务(Function as a Service,FaaS)平台上运行函数式业务代码,一般来说,它们是在受管理的、临时性的容器中执行的。

虽然新出现的基于容器的 Serverless 平台,比如 Knative,可以运行开发人员使用传统方式开发的应用,但 FaaS 仍然是 Serverless 中最重要、最具代表性的产品形态,因为它让我们以一种不同于传统的方式思考技术架构。

FaaS 中的“Function”就是不依赖特定框架和类库的最纯粹的业务代码——这是真正为业务带来价值的东西。可以说,FaaS在将云应用中的非业务代码部分进行最大化剥离方面做到了极致。我认为它是云原生“皇冠上的明珠”。

不过,大家普遍认为当前FaaS更适合开发事件驱动风格的、处理少数几个事件类型的应用组件,而不适合开发传统的具有很多入口的同步请求/响应风格的应用组件。也就是说,如果你想问:“能不能基于 FaaS 做出一个 SAP ERP?”目前可能大多数人给你的答案会是“NO”。

但是我想给你的答案是“YES”!因为要想达到这个目标,我们需要克服的所有障碍都不属于 FaaS 的固有缺点,而是当前FaaS 的实现缺陷,比如启动延迟、集成测试、调试、交付、监控与观测等方面的问题。

我认为,以 DDD 方法实现的应用可以极大地降低 FaaS 处理这些问题的难度,甚至可以直接忽视某些问题(因为它们对以 DDD 方法实现的应用来说不是问题)。具体而言,我们可以使用 DDD 的聚合概念来切分应用组件,每个聚合一个小组件,它们可以很快地被 FaaS 平台“拉起”。这些高度内聚的小组件是更复杂的应用组件(比如说领域服务)的构造块。我们可以使用兴起于 DDD 社区的 Event Sourcing(事件溯源,ES)模式,保证应用状态的每一次变更都会发布领域事件,并以富含业务语义的事件驱动其他应用组件运行。比如,命令查询职责分离(Command Query Responsibility Segregation,CQRS)模式中的 Denormalizer(去规范化器)组件就可以订阅、消费这些事件,为前端应用构建友好的查询视图——这些都是 DDD 社区在开发严肃的商业软件时一直在做的事情。如果之前你没有接触过聚合、ES、CQRS,也许难以理解上面所说的内容,不过没关系,读完本书,我相信你就清楚了。

再说“中台”这个热词。以我的理解,中台是将可复用的代码抽取到一个平台中,作为大家共用的软件组件,它是服务于前台的规模化创新。中台(这里主要指业务中台)想要好用,必须具备“反映对领域的深度认知”的软件模型,甚至在某种程度上需要“过度设计”,并且绝对有必要维护良好的概念完整性,构建所谓的企业级业务架构——这些都是 DDD 可以大展身手的地方。

关于“产业互联网即将进入黄金时代”的说法,大多是众多传统企业希望借力最新的信息化,特别是互联网工具(即所谓“互联网+”),提升内部效率和对外服务的能力。传统产业中的很多领域概念和业务流程并不一定为普通的开发者所熟知——这与“消费互联网”不同,显然人人都是消费者。所以,传统产业的信息化急需可以快速梳理并深刻地认知领域,以及能构建高质量领域模型的技术人才。DDD 可以说是技术人员升职加薪的“神兵利器”。

我在工作中看到的情况是,越来越多的技术人员在自己的求职简历上写上了“熟悉(或精通)DDD”的描述。确实,Eric Evans 的经典著作以抽象、凝练著称,可谓字字珠玑,甚至很多资深技术人员都不能领悟其中玄妙。所以,我也认同掌握 DDD 是一件足以让技术人员引以为傲的事情。

可以说,DDD 是公认的解决软件核心复杂性的“大杀器”。但是,在软件开发中实践 DDD 是需要付出相当大的成本的。也就是说,大家的普遍看法是:实践 DDD 是一个先苦后甜的过程,一个项目要不要采用DDD,最好先看看它值不值得。

但是一个项目值不值得使用 DDD 有时不好判断。大项目往往是由小项目发展而来的,很多从小项目演化而来的大系统最终变成开发团队的噩梦,噩梦的根源几乎无一例外地在于软件的概念完整性遭到了破坏。而DDD正是维护软件概念完整性的良药。如果在项目中实践 DDD 的成本不高,那么即使是小项目,从一开始就使用 DDD 不是一件很美好的事情吗?

在软件开发项目中实践 DDD 到底有何难处?16 年了,难道在 DDD 实践中碰到的问题我们不能从书本中寻得答案?

目前国内已经出版的DDD相关图书中,除了 Eric Evans 的经典著作之外,还有《实现领域驱动设计》《领域驱动设计精粹》《领域驱动设计模式、原理与实践》等,不过寥寥数本。这与 DDD 的巨大声望很不匹配,这也许说明了一些问题。

实践DDD首先需要面对的一个(也许是最大的)难题是:难以描述的领域模型。

DDD 想要构建的领域模型是什么?按照 Eric Evans 的观点,领域模型不是一幅具体的图,而是那幅图想要传达的思想;不是一个领域专家头脑中的知识,而是那些经过严格组织并进行选择性抽象的知识。

听起来是不是有点玄奥?系统分析师、产品经理到底要拿出什么样的领域模型才能说

“我的工作已经做到位了”?这个模型到底是不是可以实现的?开发人员、测试人员到底有没有理解这个模型?大家的理解是不是一致的?

说到底,一个领域模型要想有用,它必须足够严格。如何使用一种严格的方式描述经过严格组织并进行选择性抽象的知识呢?

问题的答案很自然地指向了 DSL。

其实,Eric Evans 早就意识到了这一点。他曾经在访谈中说:

更多前沿的话题发生在领域专用语言(DSL)领域,我一直深信 DSL 会是领域驱动设计发展的下一大步。现在,还没有一个工具可以真正给我们想要的东西。但是人们在这一领域比过去做了更多的实验,这使我对未来充满了希望。

通过本书,我想要告诉大家的是:在项目中运用 DDD 可以不像大家想象的那么痛苦,DDD 并不是只适用于大项目,使用 DDD 并不一定需要牺牲敏捷性,一切的关键在于 DSL 的运用。

我和我工作过的团队曾经在多个项目中使用 DSL 实现了 DDD 的真正落地。独乐乐不如众乐乐!现在,我想把这些实践经验分享给大家。


【读者对象】

领域模型是一种“思想”,它可以为软件开发的全过程提供指导,所以我相信本书可以为很多人提供帮助:

产品经理与系统分析师。产品经理不仅仅需要保证团队开发的是“正确的软件”,也不应该只是关注软件的界面原型、用户体验,更应该让软件有内涵。迷人的产品不仅需要漂亮的界面和交互,更需要逻辑自洽,功能处处传达出一个思想——优美而深刻的领域模型。在有的团队中,产品经理同时也是系统分析师。作为近十几年来最有影响力的软件分析和设计的方法论,系统分析师有必要了解DDD,从中汲取营养。

架构师。架构师需要根据业务需求提供技术解决方案。DDD 想要构建的领域模型不仅仅是领域业务知识的提炼总结,也包含了对软件设计的考量,可以用于直接指导软件的编码实现。构建这样的模型,需要架构师的积极参与。

开发工程师。开发工程师应该理解领域模型,领域模型应该被忠实地映射到代码实现中。代码中对象的命名、对象之间的关系,都应该与领域模型一致。唯有如此,代码才能具备良好的可读性、可维护性,敏捷 XP 方法的狂热爱好者们所言的“代码即文档”才可能实现。

测试工程师。如今很多测试工程师已经被称为“测试开发工程师”,他们也应该理解领域模型。测试工程师应该像产品经理一样了解软件的设计,甚至应该比产品经理更深刻地理解领域模型面向软件设计所做的考量。实例化需求的自动化测试(或者说行为驱动测试)应该基于领域模型,而非基于 UI/UE 来构建,因为用户界面以及用户交互是易变的,而领域模型相对来说稳定得多。

项目经理。项目经理是负责“正确开发软件”的人。如果不深刻理解领域,不知道如何抓住领域模型中的关键点,会很难评估任务工作量的大小以及应该在何处投入足够的资源,甚至无法判断项目的实际进度。

高校研究生以及其他有志于从事 IT 行业的人。


【如何阅读本书】

本书的第一部分会带领读者从战术层面以及战略层面重温领域驱动设计的重要概念,然后进一步阐述Eric Evans经典著作中没有显式提出的或者被太多人忽略的但我认为对 DDD 落地非常重要的若干概念,同时简要介绍从 DDD 社区兴起的一些软件架构模式。通过第一部分,读者可以更完整、更深刻地掌握 DDD 的知识体系。

第二部分阐述如何设计一种DDD的DSL,包括这个DSL的规范(Specification)支持哪些特性、如何帮助团队描述领域模型的方方面面、这些特性的选择基于何种考量等。

这种领域专用语言需要一个名字,我们总不能一直说“我设计的 DDD 的 DSL”吧,于是我给它起了一个名字:DDDML。我认为这是一个很棒的名字。其实这种语言叫什么并不太重要,重要的是它可以用一种足够严格的方式描述领域模型。我认为目前它在简单与复杂之间取得了不错的平衡。当然,其中还有不小改进的空间。比如,我很乐意让它支持更多像“账务模式”这样的分析模式。

第三部分介绍如何将“思想照进实现”——通过使用工具将描述领域模型的 DSL 文档变成可以运行的软件。这个过程涉及大量的技术工具(工具链)的设计与实现。只有将这些技术工具——比如从 DSL 自动生成应用的源代码的模板——实现出来,才能减轻开发人员实践 DDD 的负担,进而提升而不是降低软件团队的生产效率。本部分会介绍这些技术工具设计与实现的细节。

我和我的同事把自制的 DDDML 工具链称为 DDDML Tools。出于商业原因,我无法展示这些工具的源代码,但是会详尽地展示这些工具运行的结果——主要是由工具生成的应用的源代码。这些源代码可能经过一些简化,但是与我们在生产系统上运行的代码十分接近,完全可以说明问题。

读完全书,你将发现其实我们已经全无秘密。你会熟知 DDDML 的规范,见到工具运行的结果,你几乎可以马上动手制造自己的 DDDML 工具。其实设计 DDDML 的规范才是整件事情(使用 DSL 实现领域驱动设计)中最难的部分,制作工具不是。虽然想要复刻我们已经做过的所有工具确实需要相当大的工作量,但也仅仅是工作量而已。

幸运的是,你并不需要制造整条 DDDML 的工具链才可以享受使用 DSL 的乐趣。比如,你可以先写一些模板,生成一些持久对象(Persistant Object),它们无非是一些简单的 Java 对象(Plain Ordinary Java Object,POJO),然后再生成一些 O/R Mapping XML,就可以马上使用 JPA/Hibernate 来实现应用的 DAL(数据访问层)了。如果你再生成 Repository,那就更漂亮啦!

第四部分讲述的是一些建模案例以及其他与 DDD 相关的话题。领域模型是一种思想,DSL 是一种工具,但是如何运用、结果如何,因人而异。我希望通过轻松的漫谈和随想,将我的一点DDD应用经验分享给大家。