DDD 战术设计概念
TMF2 中的概念:
领域能力:
扩展点:
DDD 战术设计使用场景
复杂业务场景
复杂来源面对的需求方更加多样化。
- 1 相同场景不同垂直业务方的需求(1688,淘宝,天猫...)
- 2 自身产品化的需求(限时购,拼团,自主订单...)
共享交易中台演进
复杂业务系统的演进 - 简书
DDD 战术设计核心思想
复用!复用!复用!
流程复用
主流程复用
子流程复用
能力复用
DDD 架构设计
DDD 模块设计
uc-common
负责定义模型和接口,子模块包括:
- uc-base-common(通用工具模块)
- uc-infra-common(基础设施通用模块)
- uc-domain-common(领域层通用模块)
- uc-service-common(应用层通用模块)
uc-base-common
职责描述
定义工具,枚举,通用模型。
包说明
﹂|enmu 通用枚举
﹂|model 通用模型(DTO)在所有模板传递(避免在多个分层中转换逻辑)
﹂|util 通过工具
uc-domain-common
职责描述
负责每个领域内部设计
- 领域服务接口
- 领域能力接口
- 扩展点接口
- 领域模型,聚合
包说明
﹂|authorize 授权领域根路径
﹂|model 领域模型
﹂|ability «interface» 领域能力接口
﹂|extension «interface» 扩展点接口
﹂|service «interface» 领域服务接口
uc-infra-common
职责描述
负责每个领域仓库设计,防腐层设计
- 仓库接口设计
- 防腐层接口设计
包说明
﹂|authorize 授权领域根路径
﹂|remote «interface» 防腐层接口
﹂|repository «interface» 仓库接口
uc-service-common
职责描述
负责应用层设计
- 应用层接口设计
包说明
﹂|authorize 授权领域根路径
﹂|service «interface» 应用层服务接口
uc-admin-interface
职责描述
用户接口层,核心针对外部协议适配,Http协议Controller,RPC协议Service.核心是二进制从网络中获取转换成DTO,坐业务处理,并将DTO转换成二进制在网络中返回。主要关注协议,框架(SpringMvC,Dubbo)实现
用户接口层职责:
- 1 参数校验
- 2 调用应用层服务
- 3 do->dto(VO)
包说明
﹂|config web 配置
﹂|exception 全局异常配置
﹂|web Controller 实现
uc-authorize-application
职责描述
应用层是很薄的一层,不应该有业务规则或业务逻辑,主要关注业务流程。
实现 uc-service-common 模块接口
对于复杂的业务:可以将业务流程定义在应用引擎层
对于简单的业务:可以将业务流程在应用层实现,通过调用领域服务编排流程
简单的业务:
Common 实现
- dto->do转换
- 仓库加载do
- 调用领域服务 (业务流程编排一个步骤)
- 调用领域服务 (业务流程编排一个步骤)
- 调用领域服务 (业务流程编排一个步骤)
- 仓库保存DO
- 防腐层发生通知
Query 实现
- 仓库查询Do Or 调用领域服务查询Do
- 调用防腐层获取dto(如果Do无法满足Vo时候)
- do -> dto(Vo) 转换 Or do,dto -> dto(Vo)
复杂业务交给流程引擎层完成。
包说明
﹂|converter dto-do 相互转换
﹂|impl 应用服务实现
uc-authorize-domain
职责描述
领域层负责进行业务逻辑操作,业务计算(内存计算),关注业务(而非技术实现),技术无关性,领域层是需要被仓库和防腐层保护起来
判定领域服务好坏很重要标准就是技术无关系,外部依赖无关!
因此我们设计更应该从上至下设计,不要想怎么存储,只用想业务逻辑!
- 存储实现包装到仓库中
- 防腐层实现包装到防腐层中
实现 uc-domain-common 模块接口
- 域服务实现
- 域能力实现
- 扩展点实现
领域服务/能力/扩展点
领域能力:面向场景的过程(步骤)
能力 :面向模型能力
扩展点:
包说明
﹂|ability 领域能力实现
﹂|service 领域服务实现
﹂|extension 扩展点实现
uc-authorize-infra
职责描述
基础层负责对业务进行技术实现,其中包括存储持久化实现,外部调用实现,关注技术,性能
实现 uc-infra-common 模块接口
包说明
﹂|config 持久化配置
﹂|expand 扩展实现
﹂|remote 防腐层实现
﹂| A服务
﹂| B服务
﹂| C服务
﹂|repository 仓库实现
﹂|cache 缓存实现
﹂|co 缓存数据模型
﹂|es 搜索引擎实现
﹂|eo 搜索引擎数据模型
﹂|mapper ORM持久化实现
﹂|po 持久化数据模型
﹂|converter 转换器
﹂|impl 仓储实现(其内部依赖缓存实现,搜索引擎实现,ORM持久化实现)
QA
为什么使用没有使用充血模型 ?
- 1 充血模型会导致所有的能力方法都放在聚合中,导致聚合对象过大,而能力本身是可以根据接口进行分类,代码可读性不高。
- 2 JAVA 本身是高内存使用的语言,使用充血模型,需要考虑内存消耗,工厂模型,对象池等技术问题