主编推荐语
领域驱动设计里程碑之作,深度解读DDD思想,揭示使用DSL实现DDD快速落地的方法技巧,缓解复杂软件开发之痛。
内容简介
本书的第一部分会带领读者从战术层面以及战略层面重温领域驱动设计的重要概念,然后进一步阐述Eric Evans经典著作中没有显式提出的或者被太多人忽略的但我认为对DDD落地非常重要的若干概念,同时简要介绍从DDD社区兴起的一些软件架构模式。通过第一部分,读者可以更完整、更深刻地掌握DDD的知识体系。
第二部分阐述如何设计一种DDD的DSL,包括这个DSL的规范(Specification)支持哪些特性、如何帮助团队描述领域模型的方方面面、这些特性的选择基于何种考量等。这种领域专用语言需要一个名字,我们总不能一直说“我设计的DDD的DSL”吧,于是我给它起了一个名字:DDDML。我认为这是一个很棒的名字。其实这种语言叫什么并不太重要,重要的是它可以用一种足够严格的方式描述领域模型。我认为目前它在简单与复杂之间取得了不错的平衡。当然,其中还有不小改进的空间。比如,我很乐意让它支持更多像“账务模式”这样的分析模式。
第三部分介绍如何将“思想照进实现”——通过使用工具将描述领域模型的DSL文档变成可以运行的软件。这个过程涉及大量的技术工具(工具链)的设计与实现。只有将这些技术工具——比如从DSL自动生成应用的源代码的模板——实现出来,才能减轻开发人员实践DDD的负担,进而提升而不是降低软件团队的生产效率。本部分会介绍这些技术工具设计与实现的细节。
目录
- 版权信息
- 前言
- 第一部分 概念
- 第1章 DDD的关键概念
- 1.1 自顶而下、逐步求精
- 1.1.1 DDD开创全新分析流派
- 1.1.2 什么是软件的核心复杂性
- 1.2 什么是领域模型
- 1.3 战术层面的关键概念
- 1.3.1 实体
- 1.3.2 值对象
- 1.3.3 聚合与聚合根、聚合内部实体
- 1.3.4 聚合的整体与局部
- 1.3.5 聚合是数据修改的单元
- 1.3.6 聚合分析是“拆分”的基础
- 1.3.7 服务
- 1.4 战略层面的关键概念
- 1.4.1 限界上下文
- 1.4.2 限界上下文与微服务
- 1.4.3 防腐层
- 1.4.4 统一语言
- 1.5 ER模型、OO模型和关系模型
- 1.6 概念建模与模型范式
- 第2章 其他DDD相关概念
- 2.1 领域ID
- 2.1.1 自然键与代理键
- 2.1.2 DDD实体的ID需要被最终用户看到
- 2.1.3 什么时候使用代理键
- 2.2 ID、Local ID与Global ID
- 2.3 命令、事件与状态
- 第3章 CQRS与Event Sourcing
- 3.1 命令查询职责分离
- 3.2 事件溯源
- 3.3 From-Thru模式
- 3.3.1 示例:ProductPrice
- 3.3.2 示例:PartyRelationship
- 3.4 CQRS、ES与流处理
- 第二部分 设计
- 第4章 DDD的DSL是什么
- 4.1 为什么DDD需要DSL
- 4.1.1 为什么实现DDD那么难
- 4.1.2 搞定DDD的“锤子”在哪里
- 4.2 需要什么样的DSL
- 4.2.1 在“信仰”上保持中立
- 4.2.2 DDD原生
- 4.2.3 在复杂和简单中平衡
- 4.2.4 通过DSL重塑软件开发过程
- 4.3 DDDML——DDD的DSL
- 4.3.1 DDDML的词汇表
- 4.3.2 DDDML的Schema
- 4.4 DDDML示例:Car
- 4.4.1 “对象”的名称在哪里
- 4.4.2 使用两种命名风格:camelCase与PascalCase
- 4.4.3 为何引入关键字itemType
- 第5章 限界上下文
- 5.1 DDDML文档的根结点下有什么
- 5.2 限界上下文的配置
- 5.3 名称空间
- 5.3.1 再谈PascalCase命名风格
- 5.3.2 注意两个字母的首字母缩写词
- 5.4 关于模块
- 第6章 值对象
- 6.1 领域基础类型
- 6.1.1 例子:从OFBiz借鉴过来的类型系统
- 6.1.2 例子:任务的触发器
- 6.2 数据值对象
- 6.3 枚举对象
- 第7章 聚合与实体
- 7.1 用同一个结点描述聚合及聚合根
- 7.2 实体之间只有一种基本关系
- 7.3 关于实体的ID
- 7.4 不变的实体
- 7.5 动态对象
- 7.6 继承与多态
- 7.6.1 使用关键字inheritedFrom
- 7.6.2 超对象
- 7.7 引用
- 7.7.1 定义实体的引用
- 7.7.2 属性的类型与引用类型
- 7.8 基本属性与派生属性
- 7.8.1 类型为实体集合的派生属性
- 7.8.2 类型为值对象的派生属性
- 7.9 约束
- 7.9.1 在实体层面的约束
- 7.9.2 在属性层面的约束
- 7.10 提供扩展点
- 第8章 超越数据模型
- 8.1 实体的方法
- 8.1.1 聚合根的方法
- 8.1.2 非聚合根实体的方法
- 8.1.3 属性的命令
- 8.1.4 命令ID与请求者ID
- 8.2 记录业务逻辑
- 8.2.1 关于accountingQuantityTypes
- 8.2.2 关于derivationLogic
- 8.2.3 关于filter
- 8.2.4 使用关键字referenceFilter
- 8.2.5 业务逻辑代码中的变量
- 8.2.6 说说区块链
- 8.3 领域服务
- 8.4 在方法定义中使用关键字inheritedFrom
- 8.5 方法的安全性
- 第9章 模式
- 9.1 账务模式
- 9.2 状态机模式
- 9.3 树结构模式
- 9.3.1 简单的树
- 9.3.2 使用关键字structureType
- 9.3.3 使用关键字structureTypeFilter
- 第三部分 实践
- 第10章 处理限界上下文与值对象
- 10.1 项目文件
- 10.2 处理值对象
- 10.2.1 一个需要处理的数据值对象示例
- 10.2.2 使用Hibernate存储数据值对象
- 10.2.3 处理值对象的集合
- 10.2.4 在URL中使用数据值对象
- 10.2.5 处理领域基础类型
- 第11章 处理聚合与实体
- 11.1 生成聚合的代码
- 11.1.1 接口
- 11.1.2 代码中的命名问题
- 11.1.3 接口的实现
- 11.1.4 事件存储与持久化
- 11.1.5 使用Validation框架
- 11.1.6 保证静态方法与模型同步更新
- 11.1.7 不使用事件溯源
- 11.2 Override聚合对象的方法
- 11.3 处理继承
- 11.3.1 TPCH
- 11.3.2 TPCC
- 11.3.3 TPS
- 11.4 处理模式
- 11.4.1 处理账务模式
- 11.4.2 处理状态机模式
- 第12章 处理领域服务
- 12.1 处理数据的一致性
- 12.1.1 使用数据库事务实现一致性
- 12.1.2 使用Saga实现最终一致性
- 12.2 发布与处理领域事件
- 12.2.1 编写DDDML文档
- 12.2.2 生成的事件发布代码
- 12.2.3 编写生产端聚合的业务逻辑
- 12.2.4 实现消费端领域事件的处理
- 12.3 支持基于编制的Saga
- 12.3.1 编写DDDML文档
- 12.3.2 生成的Saga命令处理代码
- 12.3.3 需要我们编写的Saga代码
- 12.3.4 需要我们实现的实体方法
- 第13章 RESTful API
- 13.1 RESTful API的最佳实践
- 13.1.1 没有必要绞尽脑汁地寻找名词
- 13.1.2 尽可能使用HTTP作为封包
- 13.1.3 异常处理
- 13.2 聚合的RESTful API
- 13.2.1 GET
- 13.2.2 PUT
- 13.2.3 PATCH
- 13.2.4 DELETE
- 13.2.5 POST
- 13.2.6 事件溯源API
- 13.2.7 树的查询接口
- 13.3 服务的RESTful API
- 13.4 身份与访问管理
- 13.4.1 获取OAuth 2.0 Bearer Token
- 13.4.2 在资源服务器上处理授权
- 13.5 生成Client SDK
- 13.5.1 创建聚合实例
- 13.5.2 更新聚合实例
- 13.5.3 使用Retrofit2
- 第14章 直达UI
- 14.1 两条路线的斗争
- 14.1.1 前端“知道”领域模型
- 14.1.2 前端“只知道”RESTful API
- 14.2 生成Admin UI
- 14.2.1 使用referenceFilter
- 14.2.2 展示派生的实体集合属性
- 14.2.3 使用属性层面的约束
- 14.2.4 使用UI层元数据
- 14.2.5 构建更实时的应用
- 第四部分 建模漫谈与DDD随想
- 第15章 找回敏捷的软件设计
- 15.1 重构不是万能灵药
- 15.2 数据建模示例:订单的装运与支付
- 15.2.1 订单与订单行项
- 15.2.2 订单与订单装运组
- 15.2.3 订单与装运单
- 15.2.4 订单的项目发货
- 15.2.5 订单的支付
- 15.3 中台是一个轮回
- 15.4 实例化需求与行为驱动测试
- 15.4.1 什么是实例化需求
- 15.4.2 BDD工具
- 15.4.3 BDD工具应与DDD相得益彰
- 15.4.4 不要在验收测试中使用固件数据
- 15.4.5 制造“制造数据”的工具
- 15.5 要领域模型驱动,不要UI驱动
- 15.6 不要用“我”的视角设计核心模型
- 15.6.1 让User消失
- 15.6.2 认识一下Party
- 15.7 我们想要的敏捷设计
- 第16章 说说SaaS
- 16.1 何为SaaS
- 16.2 多租户技术
- 16.3 构建成功的SaaS有何难
- 16.3.1 多租户系统的构建成本
- 16.3.2 难以满足的定制化需求
- 16.3.3 负重前行的传统软件公司
- 16.4 SaaS需要DDD
- 第17章 更好的“锤子”
- 17.1 我们制作的一个DDDML GUI工具
- 17.1.1 给领域建模提供起点
- 17.1.2 创建新的限界上下文
- 17.1.3 从OFBiz中“借鉴”数据模型
- 17.1.4 构建项目并运行应用
- 17.1.5 使用HTTP PUT方法创建实体
- 17.1.6 给聚合增加方法
- 17.1.7 生成限界上下文的Demo Admin UI
- 17.1.8 让不同层级的开发人员各尽其能
- 17.2 以统一语言建模
- 附录 DDDML示例与缩写表
出版方
机械工业出版社有限公司
机械工业出版社是全国优秀出版社,自1952年成立以来,坚持为科技、为教育服务,以向行业、向学校提供优质、权威的精神产品为宗旨,以“服务社会和人民群众需求,传播社会主义先进文化”为己任,产业结构不断完善,已由传统的图书出版向着图书、期刊、电子出版物、音像制品、电子商务一体化延伸,现已发展为多领域、多学科的大型综合性出版社,涉及机械、电工电子、汽车、计算机、经济管理、建筑、ELT、科普以及教材、教辅等领域。