领域驱动设计-Domain-Driven-Design

DDD

Posted by Claire on November 18, 2020

领域驱动设计-Domain-Driven-Design

一、Evans DDD 是什么

1.1 背景

  • 2002年,敏捷宣言诞生
  • 时代处于 CS 到 BS 的转换时期
  • 2003年 Eric Evans 发表<领域驱动设计>
  • 2013年 微服务诞生,微服务的拆分和边界限定成为了难点,因而DDD思想开始重新发挥作用

1.2 描述

  • 2003 Eric Evans : Domain-Driven Design - Tackling Complexity in the heart of Software 领域驱动设计
  • 领域建模是一种艺术的技术
  • 面向对象建模方法,是一种工程方法论
  • 是用来解决大型复杂软件快速应付变化的解决之道
  • 属于业务架构设计范畴
  • 使系统有较好的一致性和良好的扩展性

1.3 重要性

  • 没有领域模型,只靠代码编写,复杂的领域需求会使得他们无法交流讨论,使工作陷入泥沼
  • 有少许领域模型,没有维护好模型和代码之间的联系,两者产生差异,无法实现

1.4 存在的问题

  • 自身概念复杂,学习难度大,门槛高
  • 国内实践少,参考少,尝试成本高
  • 敏捷迭代,使得项目放弃了建模

二、为什么使用MDD/DDD

2.1 MDD 模型驱动设计

2.2 MDD = DDD+DSL(领域特定语言)

2.3 优点

  • 真正快速开发
  • 更具成本优势
  • 引导质量提高
  • 很少出错
  • 不在乎人事变动
  • 授权领域专家
  • 能够让高级程序员专攻难关
  • 让业务和IT之间架设了桥梁
  • 减少业务需求带来的影响面
  • 导致技术对变化不是太敏感
  • 增强架构
  • 可以截获领域知识
  • 能够关注业务而不是技术

  • 架构发展阶段

    • 单体
    • MVC
    • SSM
    • 分层
    • DDD分层
    • 对称性分层

三、软件开发本质

3.1 问题空间

  • 需求、用例、业务分析

    • 领域问题:一个特定边界内的业务需求总和

3.2 解决方案空间

  • 模型、组件、架构、设计实现

    • 领域模型:是业务功能场景在软件系统的映射转化

3.3 映射转化

四、分析设计发展阶段

4.1 主要阶段

  • 围绕数据库的驱动设计

    • 设计从数据库表设计开始
  • 面向对象的分析设计

    • 区分分析和设计阶段,两个阶段是比较割裂的
  • 融合了分析和设计阶段的领域驱动设计

4.2 不同阶段局限性

  • 传统数据库方式的局限性

    • 分析方面

      • 不能迅速有效全面分析需求
    • 设计方面

      • 导致过程化设计编程,丧失了面向对象设计的特点,对象仅成为数据的载体
    • 运行方面

      • 导致软件运行时负载集中在数据库端,难于扩展
    • 其他

      • 对象与关系型数据库的天然阻抗

        • 库表关系不能真正还原对象之间的联系,需要额外字段
        • CRUD的操作,不能直观标识对对象的意图
        • 数据模型和关系模型存在偏差
  • 面向对象:分析和设计割的局限性

    • 分析人员负责从问题空间领域汲取需求,即从需求领域着手
    • 设计人员:剥离出能够通过编程构建的组件,组件间能够有效运作,解决应用程序的问题
    • 迭代的需求,不能很好的分析,由设计人员按照数据的逻辑进行拼凑
    • 两个阶段目标不一致,导致割裂,项目失败

4.3 DDD领域模型特点

  • 统一语言/通用语言

    • 项目中统一交流的语言,提高交流效率、工作效率、避免理解错误与误解、沟通低效
    • 让应用能和业务相匹配,通过在业务与代码中的技术之间采用共同的语言达成的
  • 统一领域模型

    • 只有业务,没有技术
    • 表达需求真实世界的模型,和软件技术无关
    • 通过分层,将领域模型层突出,其他为辅助

五、分层架构

5.1 分层详情

  • 表现层

    • 与MVC的V类似,关注显示和用户指令
  • 应用层

    • 与MVC的C类似,指挥领域对象实现功能,精简
  • 领域层

    • 核心业务概念
  • 基础支撑层

    • 与MVC的M类似,与软件技术相关

5.2 分层架构优点

  • 不同层级,能够保证高内聚低耦合,有利于程序分布式部署、提升心梗、高可伸缩性

六、DDD实施的注意点

6.1 挖掘核心深层模型

6.2 剔除反面通用子域

6.3 内聚机制

6.4 隔离核心

6.5 领域模型切割

6.6 行为型设计模式

  • 模板方法
  • 策略
  • 状态
  • 命令
  • 迭代器
  • 备忘录
  • 观察者
  • 中介者
  • 访问者
  • 责任链
  • 解释器

七、领域模型元素

7.1 实体

  • 拥有业务含义的全局唯一标识符,拥有生命周期,且标识符在经历软件系统的各种状态,生命周期后仍能保持一致

7.2 值对象

  • 一般来说不需要有业务含义的唯一标识符,因为我们并不关心它是谁
  • 值对象和实体是整体
  • 值对象是不变的,可共享
  • 值对象复制

    • Java clone

7.3 服务

  • 行为接口

7.4 领域对象生命周期

7.5 聚合

  • 一组相关联的对象,出于数据变化的目的,将它们视为一个单元

    • 汽车中:轮胎+车架+座椅
    • 汽车中:引擎
    • 汽车中:驾驶员+乘客
  • 聚合中的不变性

    • 划出不变性和可变部分

7.6 工厂

  • 工厂用来封装对象创建所必需的知识,它们对创建聚合特别有用

    • 抽象工厂
    • 工厂方法
  • 属于领域层

7.7 组合

  • Hibernate O/R Mapping框架,实现对象的创建和组合

7.8 客户端只关心模型,而不是数据存储,存储和访问都交给Repository完成,避免数据库规范扰乱模型的整洁

限界上下文

  • 确定语义所在的领域边界,边界定义了模型的适用范围,使团队所有成员能够明确地知道什么应该在模型中实现,不应该在模型中实现

7.9 4种Robbin领域模型

  • 失血模式-不提倡

    • POJO 仅有Getter/Setter方法
    • 业务逻辑和应用逻辑,都在应用层
  • 贫血模式

    • 部分业务逻辑放在domain object中
  • 充血模式

    • 大部分业务逻辑放在domain object中
  • 胀血模式-不提倡

    • 过多业务逻辑放在domain object中
  • 实体本之行为放入实体,行为跨越实体本身生命周期的,可放入服务中

八、领域服务

8.1 对一个聚合的操作,放在一个单独的接口中

8.2 CRUD是服务吗

  • 管理行为,是服务

8.3 领域层服务

  • 与业务有关,CRUD

8.4 应用层服务

  • 与软件设计有关,类似MVC中的Controller

8.5 基础层服务

  • 发送Email

九、领域事件

9.1 对聚合的操作,建成一系列离散事件

9.2 在不同场景下,由实体发出事件驱动服务,通过类似异步消息机制实现松耦合

9.3 业务规则 Specification

  • JPA进行条件筛选的时候,有Specification+仓储(Repository)的结合

十、事件风暴

10.1 构建领域模型的充满乐趣的实施方法

10.2 领域时间与架构设计的本质

  • 领域事件

10.3 事件风暴步骤

  • 头脑风暴
  • 罗列领域事件
  • 领域事件集合
  • 标注事件命令
  • 标注时间命令发起方角色
  • 领域故事分析
  • 提取领域对象
  • 领域对象与代码模型映射
  • 代码落地

十一、CQRS框架

11.1 命令与查询分析,数据查询与业务操作分离

11.2 是DDD开发风格下对领域模型按机构的一种简化改造

11.3 DDD+CQRS使用六边形对称性架构

11.4 DDD+CQRS+Event Souring 是有趣且强大的技术

十二、JiveJdon框架

12.1 JiveJdon 3.0是按照2004年国外最新设计思想”领域驱动设计”(Domain-Driven Design 简称DDD)、基于JdonFramework自主开发的复杂软件系统

12.2 开源

12.3 性能优异、可伸缩性强

12.4 可拓展性

12.5 采用组件动态设计的面向构件架构

十三、微服务框架

13.1 微服务的特征

  • 通过服务进行组件化
  • 围绕业务能力组织
  • 去中心化的治理技术
  • 去中心化的管理数据
  • 基础设施自动化
  • 容错和演进式设计

13.2 设计微服务的路径依赖困境

  • 利用拆分单体服务思维,拆分子模块,形成微服务,不可行

13.3 基于微服务的重构

  • 识别领域对象
  • 界定上下文边界
  • 使用聚合概念把关联性强的业务划分在同一个边界下
  • 限定聚合和聚合之间通过聚合根来访问
  • 结合业务限定上下文与技术因素,对服务的粒度、分层、边界划分、依赖关系、集成关系进行梳理
  • 构建通用语言,高效沟通

13.4 微服务设计方法

  • 事件风暴
  • 领域对象以及服务矩阵和代码设计
  • 领域对象以及服务矩阵

13.5 代码结构模型

  • application
  • domain
  • infrastruture
  • interface

13.6 微服务是技术实现和部署的范畴,实现领域或中台的业务逻辑,为前台应用提供服务

十四、分层架构

14.1 MVC框架改造

  • 限定上下文,将一个大领域拆分成独立的子域
  • 针对领域对象,添加领域层,提供服务
  • 用用层,组装各个领域服务,对外提供能力
  • 应用层验证、领域服务验证、领域模型验证

14.2 四层架构

14.3 五层架构

14.4 六边形架构

  • 洋葱架构

十五、更多大厂实践

15.1 阿里盒马

15.2 阿里文娱

15.3 美团外卖

  • 点评业务
  • 供应链业务

15.4 业务中台

  • 中台的本质是提炼各个业务条线的共同需求,并将这些功能打造成组件化产品,然后以 API 接口的形式提供给前台各业务部门使用
  • 从限定上下文到微服务,从应用架构到技术架构
  • 从决策到接口
  • 从领域模型到分层架构
  • 从DDD 到TDD