内容简介这是一本从业务和架构视角讲解DDD的基本原则、底层逻辑、落地难点、落地方法和进阶技巧的实战性著作。DDD的理论体系复杂,学习和实践门槛较高,已有的关于DDD的著作或多或少存在理论描述难理解、案例示范难落地等问题,阻碍了DDD在实践中的应用。本书作者有20余年的软件研发经验,对DDD有深刻的理解,深谙DDD实践过程中的痛点,他在这本书中高屋建瓴、化繁为简,让读者有拨云见雾之感。理论部分(第1~3章)从软件工程的基本思想出发,首先分析了DDD产生的原因,并由此推论出DDD的基本原则,这些内容是学习本书的基础;紧接着分析了DDD落地的难点,帮助读者扫清障碍;然后提炼出了DDD的成熟度模型,包括DDD的战略、战术和衡量指标。这些内容极具针对性和独创性,是研发团队必须掌握的,也是目前同类书中很少讲的。实战部分(第4~10章)从业务建模和架构的角度切入,首先用搭积木的方式讲解和演示了DDD项目由简易到复杂的落地过程,包含大量的业务建模场景和案例,涉及如何应用通用语言、如何建模领域逻辑、如何应用上下文和子域切分系统以及如何保持语言、模型、代码的一致性等重要内容;然后讲解了如何将各种设计模式应用到DDD中,以及如何设计出能让DDD更好落地的系统架构。这些内容兼具实操性和思想性,充满经验和智慧,在同类书中同样也不多见。
(1)作者背景:作者是亚信云研发总监,有超过20年的软件研发经验,曾就职于微软等企业。(2)作者经验丰富:作者对DDD有深刻理解,成功主导多个互联网商业项目。(3)克服同类弊病:作者用丰富的经验和深入的思考,将DDD化繁为简,克服了同类书难理解和不落地的问题,让读者拨云见雾。(4)针对性、独创性:DDD原则、DDD底层逻辑、DDD成熟度模型、DDD落地难点等多个知识点都是读者独创,极具针对性,同类书不具备。(5)实操性、思想性:用搭积木方式演示DDD项目搭建过程,将DDD与设计模式和系统架构深度融合,在同类书中同样也不多见。(6)企业界、学术界力荐:来自腾讯、华为、北交大等知名企业和学府的近10位专家高度评价并鼎力推荐。
Preface 前 言
为什么要写这本书
本书创作的初心有两个。
第一,服务于广大开发人员的职业进阶和转型。
本书讲授的是领域驱动设计(Domain-Driven Design,DDD)的相关知识。DDD是一种业务建模和架构设计方法,而业务建模和架构设计是开发人员职业进阶和转型的技能。
在当今AI技术大流行的背景下,快速掌握这两项技能对开发人员来说很重要,因为写程式化“胶水代码”的工作很快就会被AI所取代。AI加速了开发这个岗位的进化和发展,这并不是件坏事。试想一下未来开发团队的工作场景:建模师们和行业的领域专家共同完成模型的搭建,AI就帮助我们生成了相应的代码,包括测试和必要的界面,之后只要把这些代码和工作成果稍加优化,整个开发就结束了。功能实现以后,架构师登场,根据业务需要设定除功能之外的其他质量属性的要求,如安全、性能、可用性、可维护性和兼容性,并在AI的辅助下给出各个质量属性的解决方案,配合云原生或PaaS平台的部署环境,系统很快搭建完毕,上线运行。
在这个场景中,你所要做的就是把职业技能树上的建模或架构这两部分点亮。所以,如果未来本书注定会出现在你的办公桌上,不如现在就把它买回家—可以先人一步,及早开始。
有人会说,凭什么未来和你描述一样呢?是不是有蹭AI热度之嫌?好吧,撇开AI不谈(其实它并不是一个体现本书价值的关键因素),想象一下五年后的自己,任何技术人员的职业发展都是从低级到高级、技术到业务、具体到抽象的过程。即便没有AI,我们是要立志成为精通多个领域知识的建模师、架构师,还是一个只会写代码,知晓许多类库用法的技术人员?答案在你心中。更何况,上面描述的工作场景已经不是未来时态了,在很多团队中已经真真切切地开始发生。
几年之内,开发人员都会逐步转到新的工作中,开发岗位的工作内容会发生巨大变化。如前所言,这绝不是坏事,它让我们的职业迈上了新的台阶,而我们唯一要做的就是开始学习,点亮建模和架构的技能树。
本书可以成为一个不错的起点,不管你是否曾经了解过DDD、参与过模型构建,它都可以让你轻松地开始。随着阅读的深入,你会发现自己已经完全被代入了建模师和架构师的角色。
第二,推动DDD方法落地的同时促进国内软件工程思想的发展。
从20年前上学时阅读的《人月神话》《人件》,到如今敏捷、DevOps、TDD、DDD等各种方法满天飞,所有主流的软件工程思想都来源于国外。当然,由于技术发展的历史原因,这并不奇怪。我们也早已不缺少世界级的互联网公司和有实力的科技企业,但在“如何开发好软件”这个问题上,还很难看到国人的创新思维和贡献,更关键的是,我们甚至都没意识到这是个问题。
更严重的影响还在于,由于缺乏对这个问题的主动探索和深入思考,我们对外来方法论的应用大多停留在“术”的层面,缺乏对“道”的探究。有术无道止于术,有太多生搬硬套、南辕北辙的例子了,团队和企业管理者根本感受不到这些方法论带来的价值,甚至对它们产生了误解和反感。
本书与其他讲授DDD的书籍的主要区别在于,它绝不仅仅讲授方法和技巧(当然,本书在这方面也有非常丰富且创新的内容),还深入发掘了其背后的思想和原理。使用的软件工程和架构原则的分析方法也不局限于应用在DDD上,而是可以用来衡量任何方法的效能和技术决策的优劣。
本书的目的之一是在指导团队成功落地DDD的同时,激发读者对书中思维角度和分析方法的思考。因此这些思想和方法都不是完美无瑕的,而恰恰相反,笔者希望读者能在思考后给出批判性的意见。激发读者思考,终究会点燃有才华的读者的灵感之火。
读者对象
AI时代需要职业转型的开发人员、架构师及其他IT从业者。
工业制造、新兴互联网等复杂领域的软件开发团队。
计划或已经落地DDD、TDD、微服务和DevOps的软件开发团队。
技术管理者、研发效能专家和咨询顾问。
即将步入社会的计算机系大学生。
本书主要内容
第1~3章为理论部分,主要讲授DDD的底层逻辑、基本原则、价值、落地难点和成熟度模型。其中,第1章是全书的基石,特别是DDD的两个基本原则,是我们讨论后面内容的基础,读者务必仔细阅读、领悟和掌握。第2章分析了DDD落地的难点,帮助团队扫清障碍。第3章首次提出DDD成熟度模型,不仅列出了整个DDD战略和战术模式,还提出了企业收益这个对企业意义重大的衡量指标,3个成熟度阶段的划分对团队也具有重要的指导意义。
第4~10章为实操部分,主要讲授DDD的战略和战术,分别对应于业务建模和架构技术。其中,第4~6章侧重于业务建模,主要介绍如何构建领域模型和打造通用语言。第7章侧重于架构技术,主要讲授如何分割系统、构建模块。第8章主要解决DDD在编码环节可能遇到的问题。第9章则是设计模式的运用,这些模式将帮助我们得到更加智慧、更加优雅健壮的领域模型。第10章阐述DDD和系统架构之间的关系。
勘误和支持
作者在博客园(Cnblogs.com)开设了专栏讲解书中的内容并回答读者提问,读者在该网站搜索书名即可找到相关专栏并参与讨论。
目 录 Contents
前言
第1章 DDD的基本原则与价值分析1
1.1 DDD的初心1
1.1.1 软件项目成败的关键1
1.1.2 两个亟须验证的事实3
1.2 DDD的基本原则6
1.2.1 DDD的两个基本原则7
1.2.2 原则的底层逻辑10
1.3 DDD的价值分析12
1.3.1 复杂度控制12
1.3.2 架构原则16
1.3.3 团队协作20
1.4 关于DDD原则的案例23
第2章 DDD落地难点分析35
2.1 DDD的适用范围35
2.1.1 领域特性36
2.1.2 团队成熟度38
2.1.3 适用性评分表39
2.2 5个常见误区39
2.3 文化的变革44
2.3.1 领域专家的边界44
2.3.2 设计师的锤子46
2.3.3 开发人员的轮子47
2.4 团队的挑战48
2.4.1 管理者的责任48
2.4.2 开发团队的意识和技能50
2.4.3 角色重新定位51
2.5 测试、过程和架构的佳搭档52
2.5.1 测试的佳搭档:TDD和
单元测试52
2.5.2 过程的佳搭档:敏捷过程
和DevOps54
2.5.3 架构的佳搭档:六边形、
洋葱和分层架构56
第3章 DDD成熟度模型59
3.1 成熟度模型的目的及特殊性59
3.2 5个度量维度60
3.3 3级成熟度模型63
第4章 模型的要素—用例、
视图和构造块68
4.1 模型的构建步骤68
4.2 模型的场景:用例69
4.2.1 用例的定义69
4.2.2 用例的目的70
4.2.3 发现用例72
4.2.4 用例的编写73
4.3 模型的数据:类图76
4.3.1 属性77
4.3.2 方法78
4.3.3 注释、约束和关键字79
4.3.4 依赖和限定关联80
4.3.5 聚合与组合82
4.4 模型的行为:交互图83
4.4.1 时序图84
4.4.2 协作图89
4.4.3 交互图与类图的关系91
4.5 模型的变化:操作契约92
4.5.1 作用93
4.5.2 后置条件94
4.5.3 准则94
4.6 模型的构造块:实体、值对象、
领域服务95
4.6.1 实体95
4.6.2 值对象99
4.6.3 实体与值对象的比较103
4.6.4 领域服务105
第5章 从语言到模型—基础
模型构建108
5.1 设计目标108
5.2 设计之前的准备工作110
5.2.1 语言110
5.2.2 角色111
5.2.3 沟通111
5.2.4 方法113
5.2.5 工具113
5.2.6 时间115
5.3 领域模型的构建115
5.3.1 发掘领域概念116
5.3.2 创建关联118
5.3.3 定义属性123
5.3.4 分配职责125
5.3.5 触发事件128
5.3.6 处理异常134
5.4 典型的领域逻辑建模137
5.4.1 规则与约束137
5.4.2 流程与分支140
5.4.3 验证与筛选142
5.4.4 算法与计算144
5.4.5 时间与空间146
5.4.6 有状态与无状态149
5.4.7 同步与异步150
5.5 典型案例151
5.5.1 案例1:在线购物网站152
5.5.2 案例2:汽车租赁系统153
5.5.3 案例3:银行系统154
第6章 精炼模型—深入模型设计156
6.1 模型引力场:聚合156
6.1.1 聚合的定义及作用157
6.1.2 聚合规则158
6.1.3 聚合设计法则158
6.1.4 实现方法161
6.2 模型装配线:工厂163
6.2.1 为什么需要工厂163
6.2.2 厂址选择169
6.3 模型货架:存储库171
6.3.1 为什么需要存储库171
6.3.2 存储库接口175
6.3.3 存储库与工厂的区别176
6.3.4 存储库与数据访问对象的区别177
6.3.5 存储库实现的注意事项177
6.4 富二代的烦恼:基类与继承178
6.4.1 抽象、泛化与DDD178
6.4.2 通用语言与基类179
6.4.3 为多态去继承181
6.4.4 合格的子类、自然的继承关系:
Liskov原则182
6.4.5 抽象类与接口的选择183
6.5 模型质量:优秀的开发组件 184
6.5.1 精心设计领域模型的特征184
6.5.2 模型设计的基本原则186
6.5.3 为扩展性而设计188
第7章 分而治之—上下文、
模块和子域191
7.1 分离用例、模型和团队:上下文191
7.1.1 什么是上下文191
7.1.2 为什么需要上下文193
7.1.3 上下文的识别方法195
7.1.4 识别上下文的步骤199
7.1.5 同一上下文工作法200
7.1.6 跨上下文团队工作法202
7.2 重用性和稳定性:模块207
7.2.1 包的内聚性原则207
7.2.2 包的耦合性原则209
7.3 区别特殊性与一般性:子域211
7.3.1 核心竞争力:核心域211
7.3.2 周边业务:支撑域215
7.3.3 通用能力:通用域215
7.4 上下文、模块和子域之间的关系216
7.4.1 上下文和子域的关系216
7.4.2 上下文和模块的关系216
7.4.3 子域和模块的关系217
第8章 关键细节—从模型到代码218
8.1 DDD 中的代码要求