本篇起,将描述战术落地DDD遇见的问题以及解决方案。
目录:
- 落地架构
- package的划分
- 类名划分
- 模块依赖关系
- 模块参数流转
5.1 增改参数流转
5.2 查询参数流转
1. 落地架构
战术落地采用的是六边形模型架构,即app层和infra层均依赖domain层。
2. package的划分
app 应用层
- dto 应用层使用对象
- factory (dto->do的工厂,接口和实现均在infra定义)
- service 应用层逻辑
domain 领域层
- anno 常用注解
- entity 实体
- enums 常用枚举
- event 领域事件
- listener 事件监听
- messaging 生产者接口(实现在infra层)
- repository 仓库接口(实现在infra层)
- service 领域服务
- unit 工具类
- valueobject 值对象
infrastructure 基础设施层
- builder 工厂(dto->po 接口和实现均在infra层定义)
- messaging 生产者实现类
- po 数据库表映射对象
- repository 仓库实现类
3. 类名划分
DTO:API入参对象
DO:聚合根实体对象(domain object)
Entity:普通实体对象
ValueObject:值对象
PO:持久化对象
4. 模块依赖关系
可以看出,领域层是项目的核心,其余层均依赖领域层。
5. 模块参数流转
DDD架构实现了业务场景与技术细节的隔离。具体到落地中,即领域层不会感知到PO对象。这就会使得替换底层实现时变的非常容易。
5.1 增改参数流转
DDD主要处理的是增删改的操作,而删除操作一般来说就是逻辑删除,本质上即为修改操。
首先领域的开放服务通过信息传输对象(DTO)来完成与外界的数据交互;在领域内部,我们通过领域对象(DO)作为领域内部的数据和行为载体;在资源库内部,我们沿袭了原有的数据库持久化对象(PO)进行数据库资源的交互。同时,DTO与DO的转换发生在领域服务内,DO与PO的转换发生在资源库内。
与以往的业务服务相比,当前的编码规范可能多造成了一次数据转换,但每种数据对象职责明确,数据流转更加清晰。
5.2 查询参数流转
按照CQRS模型,查询操作不用走领域层,而直接由基础设施层向外提供能力。但是在DDD理论中,基础设施层对外的查询结果是聚合根对象。
但是在实际开发过程中,我们经常会遇见根据id查name的这种场景,此时不能一味的遵循理论。而应该根据实际情况来设计查询参数的流转。
- 基础设施层提供一个方法,对外返回聚合根实体对象;
- 基础设施层提供n个方法,对外返回值对象,值对象的返回便是轻量级的结果。