DDD领域驱动设计理念及总结

555 阅读8分钟

领域驱动设计(Domain-Driven Design,简称DDD)是一种面向对象软件开发方法论,旨在解决复杂业务领域的建模和设计问题。它强调通过深入理解业务领域和业务需求,将领域专家的知识融入到软件设计中,以实现高质量的软件系统。领域驱动设计的核心思想是将业务领域作为软件系统设计的核心,并围绕领域模型进行开发。

1.全景图

实现业务中台建模,基于DDD微服务建设和开发

image.png

2.基础概念

2.1 基础概念说明

  • 领域:一种特定范围或者区域,按照一定规则细分业务领域,将问题范围限定在特定的边界内,在边界内构建领域模型。DDD的领域就是在这个边界内要解决的业务问题域
    • 核心域:决定产品核心竞争力,如电商中的下单、促销
    • 通用域:被多个子域使用的通用子功能,如认证、权限
    • 支撑域:既不包含决定产品和公司核心竞争力的功能,也不包含通用功能的子域
    • 子域:对应一个更小的问题域或更小的业务范围,有领域细分
  • 通用语言:团队交流达成共识的,能够简单、清晰、准确描述业务涵义和规则的语言
  • 界限上下文:用来封装通用语言和领域对象,提供上下文环境,保证在领域之内的一些术语、业务相关对象等(通用语言)有一个确切的含义,没有二义性。
  • 实体:拥有唯一标识符的对象,具有业务属性和业务行为;代码层面DO(充血模型),数据库层面对应0个(折扣实体)、1个、多个(N对1 用户实体和账户实体放在一起 1对N 权限实体:用户和角色)
  • 值对象:没有标识符的对象,通过对象属性来识别对象,将多个相关属性组合成为一个概念整体
  • 聚合:由业务和逻辑紧密关联的实体和值对象组合而成的,聚合是数据修改和持久化的基本单元,每一个聚合对应一个仓储,实现数据的持久化。
    • 一个聚合根和上下文边界,这个边界根据业务单一职责和高内聚原则,定义了聚合内部应该包含哪些实体和值对象
    • 业务场景需要同一个聚合的 A 和 B 两个实体来共同完成,将这段业务逻辑用领域服务来实现
    • 业务逻辑需要聚合 C 和聚合 D 中的两个服务共同完成,可以用应用服务来组合这两个服务
  • 聚合根:作为实体本身,拥有实体的属性和业务行为;作为聚合的管理者,在聚合内部负责协调实体和值对象按照固定的业务规则协同完成共同的业务逻辑;以聚合根 ID 关联的方式接受外部任务和请求
    • 高内聚 低耦合
    • 微服务拆分最小单元,一个微服务可以包含多个聚合
  • 事件风暴:采用(用例分析、场景分析、用户旅程分析)方法->头脑风暴(所有业务行为和时间)->找出领域对象、聚合根、实体和值对象->构建聚合
  • 领域事件:这种事件发生后通常会导致进一步的业务操作;关键词:如果发生……,则…… 当做完……的时候,请通知…… 发生……时,则……

2.2 如何划分领域模型和微服务的边界?

三步

  1. 事件风暴中梳理业务过程中的用户操作、事件以及外部依赖关系,整理出领域实体等领域对象
  2. 根据领域实体之间的业务关联性,将业务紧密相关的实体进行组合形成聚合,同时确定聚合中的聚合根、值对象和实体,形成聚合根
  3. 根据业务及语义边界等因素,将一个或者多个聚合划定在一个限界上下文内,形成领域模型。 从业务模型向微服务落地的过程中,也就是从战略设计向战术设计的实施过程中,我们会将领域模型中的领域对象与代码模型中的代码对象建立映射关系,将业务架构和系统架构进行绑定。

image.png

2.3 微服务和DDD的关系

DDD 是一种架构设计方法,微服务是一种架构风格

  • DDD 主要关注:从业务领域视角划分领域边界,构建通用语言进行高效沟通,通过业务抽象,建立领域模型,维持业务和代码的逻辑一致性。
  • 微服务主要关注:运行时的进程间通信、容错和故障隔离,实现去中心化数据管理和去中心化服务治理,关注微服务的独立开发、测试、构建和部署。

2.4 界限上下文和微服务关系

举例: 车险承保的流程包含了投保、缴费、出单等几个主要流程。如果出险了还会有报案、查勘、定损、理算等理赔流程。
保险领域被拆分为:投保、支付、保单管理和理赔四个子域。子域还可根据需要进一步拆分为子子域,比如,支付子域可继续拆分为收款和付款子子域。拆到一定程度后,有些子子域的领域边界就可能变成限界上下文的边界了。子域可能会包含多个限界上下文,如理赔子域就包括报案、查勘和定损等多个限界上下文(限界上下文与理赔的子子域领域边界重合)。也有可能子域本身的边界就是限界上下文边界,如投保子域。
每个领域模型都有它对应的限界上下文,团队在限界上下文内用通用语言交流。领域内所有限界上下文的领域模型构成整个领域的领域模型。理论上限界上下文就是微服务的边界。我们将限界上下文内的领域模型映射到微服务,就完成了从问题域到软件的解决方案。

2.5 聚合设计原则

  • 在一致性边界内建模真正的不变条件:聚合内有一套不变的业务规则,各实体和值对象按照统一的业务规则运行,实现对象数据的一致性,边界之外的任何东西都与该聚合无关,这就是聚合能实现业务高内聚的原因。
  • 设计小聚合
  • 通过唯一标识引用其他聚合
  • 在边界之外使用最终一致性
  • 通过应用层实现跨聚合的调用

2.6 中台含义

中台是企业级能力复用平台

  • 对前台业务的快速响应
  • 企业级复用能力
  • 从前台、中台到后台的设计、研发、页面操作、流程服务和数据的无缝联通、融合能力

2.7 DDD、中台、微服务关系

中台在企业架构上更多偏向业务模型,形成中台的过程实际上也是业务领域不断细分的过程。在这个过程中我们会将同类通用的业务能力进行聚合和业务重构,再根据限界上下文和业务内聚的原则建立领域模型。而 DDD 的战略设计最擅长的就是领域建模。
那在中台完成领域建模后,我们就需要通过微服务来完成系统建设。此时,DDD 的战术设计又恰好可以与微服务的设计完美结合。可以说,中台和微服务正是 DDD 实战的最佳场景。

3.实践

3.1 分层架构

image.png 基础层依赖倒置

3.2 DDD 分层架构如何推动架构演进?

  • 微服务架构演进

image.png 聚合方式演进

  • 微服务内服务的演进

image.png 应用层下沉到领域层

3.3 DDD分层架构、整洁架构、六边形架构对比分析

image.png 作用就是将核心业务逻辑与外部应用、基础资源进行隔离
三种架构都考虑了前端需求的变与领域模型的不变

3.4 如何构建中台业务模型?

  • 自顶向下策略:适合全新的应用系统设计或者旧系统推倒重建
    • 逐级分解

image.png

  • 自底向上策略:遗留系统的渐进式重构
    • 基于现有业务和系统分析建模->对齐业务域,推导出同类领域模型,对比现状差异,重构领域模型

3.5 微服务代码架构模型

参考 【实践篇】DDD脚手架及编码规范 | 京东云技术团队
【实践篇】领域驱动设计:DDD工程参考架构 | 京东云技术团队

4.参考文档

DDD技术方案落地实践 | 京东云技术团队