DDD领域驱动设计

Domain Driven Design

1.概述

影响复杂度的3个要素:规模、结构与变化。控制复杂度的着力点就在这3个要素之上

1.1 领域驱动设计元模型

核心方法论:模型驱动设计,模型驱动设计的核心又是领域模型
为整个业务系统建立的领域模型要么属于核心子领域​,要么属于通用子领域
为了保证定义的领域模型在不同上下文表达各自的知识语境,需要引入限界上下文来确定业务能力的自治边界,并考虑通过持续集成来维护模型的统一。
上下文映射清晰地表达了多个限界上下文之间的协作关系

具体方法

  • 面向对象分析设计:用例分析,对象职责分解,通用建模
  • 四色建模:特定于商业场景建模方式
  • CQRS:只对命令类问题领域模型建模,降低建模难度
  • 事件风暴:从事件出发建模
  • 四层架构:独立的领域层
  • 六边形架构:领域模块成为架构核心,不依赖实现
  • 事件溯源:只持久化事件,不持久化聚合,解决对象模型和数据库不匹配

1.重构代码

  • 1.1 添加领域模块

    老代码依赖领域模块,领域模块只实现领域模型代码
  • 1.2 分离出有价值代码

    老代码内部分离出最有价值的模块,定义这个模块和老代码之间接口,接口非常重要
  • 1.3 迁移到领域模型

    在领域模块中按照DDD方式实现领域模型,原本老代码中待分离模块变成适配器模块,调用领域模型实现接口

2.实践路径

  • 实现模型:使用六边形架构和CQRS实现领域模型,会仓储模式
  • 战术建模:事件风暴和DDD设计模型掌握聚合,能解决简单的问题
  • 战略建模:用事件风暴对复杂业务建模,掌握限界上下文子领域
  • 协作:帮助兄弟团队理解DDD 统一语言,综合敏捷开发,架构治理等

3.六边形架构


DDD追求领域模型代码不对别的代码产生语义依赖,而编译依赖必定导致语义依赖
因此领域模型代码应该不对别的代码产生编译依赖

  • 依赖反转:领域模块中要使用非领域模块功能,只需要定义接口,在领域模块外实现该接口
  • 不是所有功能都在领域内定义接口,只有那些不可再分解为领域逻辑的功能才定义为接口
  • 在领域模块内定义的接口,应该使用领域模型的语言,不要对实现产生语义依赖

4.CQRS

Command and 命令
Query 查询
Responiblity 职责
Segrgation 分离

4.1 职责分离

命令和查询俩类功能代码分离

  • 查询模块依赖命令模块

4.2 标准架构

命令和查询通过领域事件集成:命令发布领域事件,查询模块监听事件,构建查询模型

  • 采用异步消息队列
  • 存储分开,用各自适合的格式存储到设备中
  • 领域事件: 是一种领域模型,代表领域已发生的有意义的,不可变,按时间有序

4.3 同事务存储分离

命令和查询构建在一个事务中
优点:简单,没有消息消费引发的问题
缺点: 领域模型和查询模型存储在一个数据库,命令处理延迟高

4.4 共享存储

由仓储负责触发生成查询模型
优点:简单易实现
缺点:查询模型共享领域模型,适应范围窄

4.5 应用范围

当不用CQRS就会污染领域模型时

  • 复杂查询:条件复杂,需要冗余数据,搜索
  • 高性能查询:需要查询专用数据库,异种查询存储(关系型数据库 缓存 NoSQL)

5.面向对象领域模型

5.聚合上下限

  • 问题域看:聚合是紧密联系的一组功能
  • 软件设计:内存单元,包含了一组对象,要被整存整取
  • 粒度适中:上限不要影响性能,下限不要破坏封装

6.事件风暴

一种头脑风暴形式

posted @   lwx_R  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示