当前位置:首页 > 工业技术
领域驱动设计模式、原理与实践
领域驱动设计模式、原理与实践

领域驱动设计模式、原理与实践PDF电子书下载

工业技术

  • 电子书积分:20 积分如何计算积分?
  • 作 者:(美)Scott Millett,(美)Nick Tune著
  • 出 版 社:北京:清华大学出版社
  • 出版年份:2016
  • ISBN:9787302428909
  • 页数:726 页
图书介绍:本书深入介绍了领域驱动设计的基本原理,帮助架构师为复杂领域构建应用的基本架构,以及如何高效地构建领域模型,在设计过程中使用模式等各种技术,适合中高层次的架构师和管理人员阅读。
《领域驱动设计模式、原理与实践》目录

第1部分 领域驱动设计的原则与实践 3

第1章 什么是领域驱动设计 3

1.1 为复杂问题域创建软件的挑战 4

1.1.1 未使用通用语言创建的代码 4

1.1.2 组织结构的缺乏 5

1.1.3 泥球模式将扼杀开发 5

1.1.4 缺乏对问题域的关注 5

1.2 领域驱动设计模式如何管理复杂性 6

1.2.1 DDD的战略模式 6

1.2.2 DDD的战术模式 8

1.2.3 问题空间与解空间 9

1.3 领域驱动设计的实践与原则 10

1.3.1 专注于核心领域 10

1.3.2 通过协作进行学习 10

1.3.3 通过探索和实验来创建模型 10

1.3.4 通信 11

1.3.5 理解模型的适用性 11

1.3.6 让模型持续发展 11

1.4 领域驱动设计的常见误区 12

1.4.1 战术模式是DDD的关键 12

1.4.2 DDD是一套框架 12

1.4.3 DDD是一颗灵丹妙药 12

1.5 要点 13

第2章 提炼问题域 15

2.1 知识提炼与协作 15

2.1.1 通过通用语言达成共识 16

2.1.2 领域知识的重要性 17

2.1.3 业务分析员的角色 17

2.1.4 一个持续过程 17

2.2 与领域专家一起获得领域见解 18

2.2.1 领域专家与业务相关人员的对比 18

2.2.2 对于业务的更深刻理解 18

2.2.3 与你的领域专家互动 19

2.3 有效提炼知识的模式 19

2.3.1 专注在最有意思的对话上 19

2.3.2 从用例开始 19

2.3.3 提出有力的问题 20

2.3.4 草图 20

2.3.5 CRC卡 21

2.3.6 延迟对模型中概念的命名 21

2.3.7 行为驱动开发 21

2.3.8 快速成型 23

2.3.9 查看基于纸面的系统 23

2.4 查看现有模型 23

2.4.1 理解意图 24

2.4.2 事件风暴 24

2.4.3 影响地图 25

2.4.4 理解业务模型 26

2.4.5 刻意发现 27

2.4.6 模型探讨漩涡 27

2.5 要点 28

第3章 专注于核心领域 31

3.1 为何要分解一个问题域 31

3.2 如何捕获问题的实质 32

3.2.1 超越需求 32

3.2.2 为达成什么是核心内容的共识而捕获领域愿景 32

3.3 如何专注于核心问题 33

3.3.1 提炼问题域 34

3.3.2 核心领域 35

3.3.3 将你的核心领域当作一款产品而非一个项目 36

3.3.4 通用域 36

3.3.5 支撑域 37

3.4 子域如何决定解决方案的形成 37

3.5 并非一个系统的所有部分都会经过良好设计 38

3.5.1 专注于清晰边界而非完美模型 38

3.5.2 一开始核心领域不必总是需要是完美的 39

3.5.3 构建用于替代而非重用的子域 39

3.6 如果没有核心领域怎么办 39

3.7 要点 39

第4章 模型驱动设计 41

4.1 什么是领域模型 41

4.1.1 领域与领域模型的对比 42

4.1.2 分析模型 43

4.1.3 代码模型 43

4.1.4 代码模型是领域模型的主要表现 44

4.2 模型驱动设计 44

4.2.1 预先设计的挑战 44

4.2.2 团队建模 46

4.3 使用通用语言将分析和代码模型绑定在一起 47

4.3.1 语言的生存周期将大于软件 48

4.3.2 业务语言 48

4.3.3 开发人员和业务之间的转译 48

4.4 基于通用语言进行协作 49

4.4.1 通过使用具体示例来定制出语言 50

4.4.2 教导你的领域专家专注在问题上而不要跳到解决方案 50

4.4.3 塑造语言的最佳实践 51

4.5 如何创建有效的领域模型 52

4.5.1 不要让实情妨碍一个好模型 52

4.5.2 仅对相关内容建模 53

4.5.3 领域模型都是暂时有用的 53

4.5.4 要十分清楚专业术语 54

4.5.5 限制你的抽象 54

4.6 何时应用模型驱动设计 55

4.6.1 如果它不值得花费精力,则不要尝试对其建模 56

4.6.2 专注于核心领域 56

4.7 要点 56

第5章 领域模型实现模式 59

5.1 领域层 59

5.2 领域模型实现模式 60

5.2.1 领域模型 61

5.2.2 事务脚本 64

5.2.3 表模块 67

5.2.4 活动记录 67

5.2.5 贫血领域模型 67

5.2.6 贫血领域模型和函数编程 68

5.3 要点 71

第6章 使用有界上下文维护领域模型的完整性 73

6.1 单个模型的挑战 74

6.1.1 模型的复杂性可能会增加 74

6.1.2 多个团队处理单个模型 74

6.1.3 模型语言中的歧义 75

6.1.4 领域概念的适用范围 76

6.1.5 集成遗留代码或第三方代码 78

6.1.6 领域模型并非企业模型 78

6.2 使用有界上下文划分和破除大模型 79

6.2.1 定义模型的边界 81

6.2.2 子域和有界上下文之间的差异 84

6.3 实现有界上下文 85

6.4 要点 88

第7章 上下文映射 91

7.1 一个现实情况的映射 92

7.1.1 技术的现实 92

7.1.2 组织的现实 93

7.1.3 映射一个相关现实情况 94

7.1.4 用X标记核心领域的位置 94

7.2 认识有界上下文之间的关系 94

7.2.1 防止损坏层 95

7.2.2 共享内核 96

7.2.3 开放宿主服务 96

7.2.4 分道扬镳 97

7.2.5 合作关系 98

7.2.6 一种上游/下游关系 98

7.3 传递上下文映射 99

7.4 上下文映射的战略重要性 100

7.4.1 保持完整性 100

7.4.2 解决计划的基础 101

7.4.3 理解所有权和职责 101

7.4.4 揭示业务工作流中的混乱区域 101

7.4.5 识别非技术障碍 101

7.4.6 鼓励良好的沟通 101

7.4.7 帮助加入的新员工 102

7.5 要点 102

第8章 应用程序架构 103

8.1 应用程序架构 103

8.1.1 分离应用程序的问题 103

8.1.2 从领域的复杂性中进行抽象 104

8.1.3 分层架构 104

8.1.4 依赖倒置 105

8.1.5 领域层 105

8.1.6 应用程序服务层 105

8.1.7 基础架构层 106

8.1.8 跨层通信 106

8.1.9 隔离测试 107

8.1.10 不要在有界上下文之间共享数据结构 108

8.1.11 应用程序架构与用于有界上下文的架构的对比 109

8.2 应用程序服务 110

8.2.1 应用程序逻辑与领域逻辑的对比 111

8.2.2 定义和公开能力 112

8.2.3 业务用例协作 112

8.2.4 应用程序服务表示的是用例,而不是创建、读取、更新和删除 112

8.2.5 作为实现详情的领域层 113

8.2.6 领域报告 113

8.2.7 读取模型与事务模型的对比 113

8.3 应用程序客户端 115

8.4 要点 117

第9章 团队开始应用领域驱动设计通常会遇到的问题 119

9.1 过分强调战术模式的重要性 120

9.1.1 将相同架构用于所有的有界上下文 120

9.1.2 力求战术模式尽善尽美 120

9.1.3 错误估计构造块对于DDD的价值 120

9.1.4 专注于代码而非DDD的原则 121

9.2 缺失了DDD的真实价值:协作、通信和上下文 121

9.2.1 由于低估上下文的重要性而产生大泥球 122

9.2.2 未能成功创建UL将造成歧义和误解 122

9.2.3 由于缺乏协作将只能设计专注于技术的解决方案 123

9.3 在不重要的部分花费太多时间 123

9.4 简单问题复杂化 123

9.4.1 将DDD原则应用到具有少量业务预期的琐碎领域 124

9.4.2 别将CRUD作为反模式 124

9.4.3 将领域模型模式用于每一个有界上下文 124

9.4.4 问一问自己:额外的复杂性是否值得 124

9.5 低估应用DDD的成本 125

9.5.1 尝试在没有积极专注的团队的情况下取得成功 125

9.5.2 项目背后没有领域专家时的协作尝试 125

9.5.3 在非迭代式开发方法中进行学习 125

9.5.4 将DDD应用到每一个问题 126

9.5.5 为不必要的纯粹性而牺牲实用主义 126

9.5.6 寻求验证会浪费精力 126

9.5.7 永远力求代码之美 127

9.5.8 DDD关乎的是提供价值 127

9.6 要点 127

第10章 应用DDD的原则、实践与模式 129

10.1 推广使用DDD 129

10.1.1 培训团队 130

10.1.2 与业务人员进行交流 130

10.2 应用DDD的原则 131

10.2.1 理解愿景 131

10.2.2 捕获所需的行为 131

10.2.3 理解环境的现实情况 132

10.2.4 对解决方案建模 133

10.3 探究和实验 139

10.3.1 质疑假设 139

10.3.2 建模是一项持续性活动 139

10.3.3 不存在错误的模型 140

10.3.4 灵活的代码有助于探索发现 140

10.4 让隐式内容变得显式 140

10.4.1 处理歧义 141

10.4.2 为事物命名 143

10.5 问题解决人先行,技术专家后行 143

10.6 如何才能知道我在正确地工作 143

10.6.1 好用就足够了 144

10.6.2 实践、实践、实践 144

10.7 要点 144

第Ⅱ部分 战略模式:在有界上下文之间通信 149

第11章 有界上下文集成介绍 149

11.1 如何集成有界上下文 150

11.1.1 有界上下文是独立自主的 150

11.1.2 在代码层面集成有界上下文的挑战 151

11.1.3 使用物理边界来强制实现整洁的模型 154

11.1.4 集成遗留系统 155

11.2 集成分布式有界上下文 158

11.2.1 集成用于分布式有界上下文的策略 159

11.2.2 数据库集成 159

11.2.3 平面文件集成 160

11.2.4 RPC 161

11.2.5 消息传递 162

11.2.6 REST 162

11.3 DDD使用分布式系统的挑战 162

11.4 分布式事务将损害可扩展性和可靠性 165

11.4.1 有界上下文不必彼此保持一致 166

11.4.2 最终一致性 166

11.5 事件驱动响应式DDD 167

11.5.1 展示响应式解决方案的弹性和可扩展性 168

11.5.2 异步消息传递的挑战和取舍 169

11.5.3 RPC还有价值吗 169

11.6 SOA和响应式DDD 170

11.6.1 将你的有界上下文视作SOA服务 171

11.6.2 进一步处理微服务架构 174

11.7 要点 175

第12章 通过消息传递集成 177

12.1 消息传递基础 178

12.1.1 消息总线 178

12.1.2 可靠的消息传递 180

12.1.3 存储转发 180

12.1.4 命令和事件 180

12.1.5 最终一致性 181

12.2 使用NServiceBus构建一个电子商务应用程序 182

12.2.1 系统设计 183

12.2.2 从Web应用程序发送命令 187

12.2.3 处理命令和发布事件 196

12.2.4 使用消息传递网关让外部HTTP调用变得可靠 203

12.2.5 实践中的最终一致性 211

12.2.6 有界上下文会存储其本地所需的所有数据 212

12.2.7 把所有内容都放在UI中 220

12.3 维护消息传递应用程序 223

12.3.1 消息版本管理 223

12.3.2 监控和扩展 228

12.4 将有界上下文与公共传输集成 231

12.4.1 消息传递桥 232

12.4.2 公共传输 233

12.5 要点 240

第13章 通过使用RPC和REST的HTTP来集成 241

13.1 为何选用HTTP 242

13.1.1 没有平台耦合 243

13.1.2 每个人都理解HTTP 243

13.1.3 大量的成熟工具和库 243

13.1.4 内部测试你的API 243

13.2 RPC 244

13.2.1 在HTTP上实现RPC 244

13.2.2 选择一种RPC风格 259

13.3 REST 260

13.3.1 深入浅出地解释REST 260

13.3.2 用于有界上下文集成的REST 263

13.3.3 维护REST应用程序 297

13.3.4 将REST用于有界上下文集成的缺点 298

13.4 要点 299

第Ⅲ部分 战术模式:创建有效的领域模型 303

第14章 构造块领域建模介绍 303

14.1 战术模式 304

14.2 对领域建模的模式 305

14.2.1 实体 305

14.2.2 值对象 308

14.2.3 领域服务 310

14.2.4 模块 312

14.3 生命周期模式 312

14.3.1 聚合 312

14.3.2 工厂 316

14.3.3 存储库 316

14.4 显露模式 317

14.4.1 领域事件 317

14.4.2 事件溯源 319

14.5 要点 320

第15章 值对象 323

15.1 何时使用值对象 324

15.1.1 表示描述性的、欠缺身份的概念 324

15.1.2 增强明确性 325

15.2 定义特征 327

15.2.1 欠缺身份 327

15.2.2 基于特性的相等性 327

15.2.3 富含行为 331

15.2.4 内聚 331

15.2.5 不可变 331

15.2.6 可组合性 333

15.2.7 自验证 335

15.2.8 可测试 338

15.3 常见的建模模式 339

15.3.1 静态工厂方法 339

15.3.2 微类型 341

15.3.3 规避集合 343

15.4 持久化 346

15.4.1 NoSQL 346

15.4.2 SQL 347

15.5 要点 354

第16章 实体 355

16.1 理解实体 356

16.1.1 具有身份和连贯性的领域概念 356

16.1.2 上下文依赖 356

16.2 实现实体 357

16.2.1 分配标识符 357

16.2.2 将行为推入到值对象和领域服务中 363

16.2.3 验证并强制不变性 365

16.2.4 专注于行为,而非数据 368

16.2.5 避免“建模现实世界”的谬误 371

16.2.6 分布式设计 371

16.3 常见的实体建模原则和模式 373

16.3.1 使用规范实现验证和不变条件 373

16.3.2 避免状态模式;使用显式建模 376

16.3.3 避免将接收器和设置器与备忘录模式结合使用 379

16.3.4 选用无隐藏意外影响的功能 380

16.4 要点 382

第17章 领域服务 383

17.1 理解领域服务 384

17.1.1 何时使用领域服务 384

17.1.2 领域服务解析 388

17.1.3 避免使用贫血领域模型 389

17.1.4 与应用程序服务对比 390

17.2 利用领域服务 390

17.2.1 服务层中 390

17.2.2 领域中 391

17.3 要点 397

第18章 领域事件 399

18.1 领域事件模式的实质 400

18.1.1 已经发生了的重要领域事件 400

18.1.2 响应事件 401

18.1.3 可选的异步性 401

18.1.4 内部事件与外部事件对比 402

18.2 事件处理操作 403

18.2.1 调用领域逻辑 403

18.2.2 调用应用程序逻辑 404

18.3 领域事件的实现模式 404

18.3.1 使用.Net框架的事件模型 404

18.3.2 使用内存中的总线 406

18.3.3 Udi Dahan的DomainEvents静态类 409

18.3.4 返回领域事件 412

18.3.5 使用IoC容器作为事件分发器 415

18.4 测试领域事件 416

18.4.1 单元测试 416

18.4.2 应用服务层测试 417

18.5 要点 419

第19章 聚合 421

19.1 管理复杂对象图形 422

19.1.1 选用单一遍历方向 422

19.1.2 合格的关联关系 424

19.1.3 选用ID而不是对象引用 425

19.2 聚合 428

19.2.1 围绕领域不变条件进行设计 429

19.2.2 高层次的领域抽象 429

19.2.3 一致性边界 429

19.2.4 选用较小的聚合 434

19.3 定义聚合边界 435

19.3.1 eBidder:在线拍卖案例研究 435

19.3.2 与不变条件保持一致 437

19.3.3 与事务和一致性保持一致 439

19.3.4 忽略用户界面影响 440

19.3.5 避免无用的集合与容器 441

19.3.6 不要专注于HAS-A关系 441

19.3.7 重构聚合 441

19.3.8 满足业务用例——非现实环境 441

19.4 实现聚合 442

19.4.1 选择一个聚合根 442

19.4.2 引用其他聚合 446

19.4.3 实现持久化 450

19.4.4 实现事务一致性 454

19.4.5 实现最终一致性 455

19.4.6 实现并发性 458

19.5 要点 459

第20章 工厂 461

20.1 工厂的作用 461

20.1.1 从构造中分离出应用 462

20.1.2 封装内部事物 462

20.1.3 隐藏创建类型的决策 464

20.1.4 聚合上的工厂方法 466

20.1.5 用于重构的工厂 467

20.1.6 务实地使用工厂 469

20.2 要点 469

第21章 存储库 471

21.1 存储库 471

21.2 一种被误解的模式 473

21.2.1 存储库是一种反模式吗 473

21.2.2 领域模型和持久化模型之间的区别 474

21.2.3 通用存储库 475

21.3 聚合持久化策略 477

21.3.1 使用能在不损坏领域模型的情况下将其映射到数据模型的持久化框架 478

21.3.2 使用不能在不影响领域模型的情况下直接映射它的持久化框架 478

21.3.3 公共接收器和设置器 479

21.3.4 使用备忘录模式 480

21.3.5 事件流 482

21.3.6 求真务实 483

21.4 存储库是一个明确的约定 483

21.5 事务管理和工作单元 484

21.6 保存或不保存 488

21.6.1 持久化追踪领域对象变更的框架 489

21.6.2 必须将变更显式保存到聚合 490

21.7 充当防止损坏层的存储库 491

21.8 存储库的其他职责 491

21.8.1 实体ID生成 492

21.8.2 集合汇总 494

21.8.3 并发性 494

21.8.4 审计追踪 498

21.9 存储库反模式 498

21.9.1 反模式:不要支持即席查询 498

21.9.2 反模式:延迟加载是一种设计异味 499

21.9.3 反模式:不要为了报告需要而使用存储库 499

21.10 存储库实现 499

21.10.1 持久化框架可以在不损坏领域模型的情况下将其映射到数据模型 500

21.10.2 持久化框架不能在不损坏领域模型的情况下直接映射领域模型 550

21.11 要点 586

第22章 事件溯源 587

22.1 将状态存储为快照的限制 588

22.2 通过将状态存储为事件流来获得竞争优势 589

22.2.1 时态查询 589

22.2.2 投影 590

22.2.3 快照 591

22.3 源自事件的聚合 591

22.3.1 构造 592

22.3.2 持久化与再融合 596

22.4 构建一个事件存储 603

22.4.1 设计一种存储格式 604

22.4.2 创建事件流 605

22.4.3 附加到事件流 606

22.4.4 查询事件流 606

22.4.5 添加快照支持 607

22.4.6 管理并发性 609

22.4.7 一个基于SQL Server的事件存储 613

22.4.8 构建你自己的事件存储是一个好主意吗 619

22.5 使用专门构建的Event Store 619

22.5.1 安装Greg Young的Event Store 619

22.5.2 使用C#客户端库 620

22.5.3 运行时态查询 624

22.5.4 创建投影 627

22.6 使用事件溯源的CQRS 629

22.6.1 使用投影创建视图缓存 630

22.6.2 CQRS和事件溯源协作 630

22.7 简要复述事件溯源的好处 631

22.7.1 竞争性业务优势 631

22.7.2 专注于表述性行为的聚合 631

22.7.3 简化的持久化 632

22.7.4 更好的调试 632

22.8 衡量事件溯源的代价 632

22.8.1 版本控制 632

22.8.2 要学习的新概念和要磨练的技能 632

22.8.3 需要学习和掌握的新技术 633

22.8.4 大量的数据存储需求 633

22.9 额外的学习资源 633

22.10 要点 633

第Ⅳ部分 有效应用程序的设计模式 637

第23章 应用程序用户界面的架构设计 637

23.1 设计考量 638

23.1.1 占有式UI与构成式UI的对比 638

23.1.2 HTML API与数据API的对比 640

23.1.3 客户端与服务器端聚合/协作对比 641

23.2 示例1:用于非分布式有界上下文的一个基于HTML API的、服务器端的UI 643

23.3 示例2:用于分布式有界上下文的一个基于数据API的客户端UI 650

23.4 要点 658

第24章 CQRS:一种有界上下文的架构 659

24.1 为两个上下文维护单个模型的挑战 660

24.2 用于复杂有界上下文的一种更好的架构 661

24.3 命令端:业务任务 662

24.3.1 显式建模意图 662

24.3.2 不受展现干扰所影响的模型 663

24.3.3 处理业务请求 665

24.4 查询端:领域报告 665

24.4.1 直接映射到数据模型的报告 666

24.4.2 从领域事件中构建的具体化视图 667

24.5 对CQRS的误解 668

24.5.1 CQRS很难 668

24.5.2 CQRS是最终一致的 668

24.5.3 模型需要源自事件 669

24.5.4 命令应该是异步的 669

24.5.5 CQRS仅适用于消息传递系统 669

24.5.6 需要将CQRS用于领域事件 669

24.6 可以扩展应用程序的模式 669

24.6.1 扩展读取端:一个最终一致的读取模型 670

24.6.2 扩展写入端:使用异步命令 672

24.6.3 对一切进行扩展 673

24.7 要点 674

第25章 命令:用于处理业务用例的应用程序服务模式 677

25.1 区分应用程序逻辑和领域逻辑 678

25.1.1 应用程序逻辑 678

25.1.2 来自应用程序服务角度的领域逻辑 690

25.2 应用程序服务模式 690

25.2.1 命令处理程序 690

25.2.2 发布/订阅 694

25.2.3 请求/回复模式 696

25.2.4 async/await 698

25.3 测试应用程序服务 699

25.3.1 使用领域专业术语 699

25.3.2 测试尽可能多的功能 700

25.4 要点 702

第26章 查询:领域报告 703

26.1 有界上下文中的领域报告 704

26.1.1 从领域对象中派生报告 704

26.1.2 直接访问数据存储 710

26.1.3 从事件流构建投影 716

26.2 跨有界上下文的领域报告 723

26.2.1 复合UI 723

26.2.2 单独的报告上下文 724

26.3 要点 726

相关图书
作者其它书籍
返回顶部