DDD中哪些对象是DTO?
DTO-Data Transfer Object,数据传输对象,用作数据传输。在落地DDD的实践中,由于采用CQRS模式,所以会有大量的Command对象、Query对象以及返回给前端用的ViewModel对象,和其他系统交互的DTO对象,这些对象都应该归类为DTO对象。
DTO对象在哪层使用?
我们在落地DDD的时候项目分层是interface层(与外部交互)、ApplicationService层(应用服务层,interface会调用本层)、Domain层(核心业务逻辑层)、infrastructure层(技术细节层,如数据库、具体实现),Domain位于最里层被其他层依赖。
- 针对对领域模型的命令对象
应该将Command对象创建在ApplicationService层,因ApplicationService是领域层的边界,类似于细胞壁,所有进入到ApplicationService层里面的数据都应该是领域对象。Command对象创建在应用层可以避免应用层对其他层的依赖。 - 针对查询对象
查询对象Query如果采用CQRS模式相对要求比较松,既可以放在ApplicationService层,也可以放在interface层,查询对象不改变领域模型 - 针对领域层产生的值对象
领域层产生的值对象应该在ApplicationService层出口之前封装成DTO,避免领域层对象泄露到外部,导致其他层或者其他系统产生依赖
有关DO对象的复用问题
与数据库交互的DO对象,在CQRS查询的时候一般直接通过Mapper进行查询,那么查出来的对象就是DO对象,在这个过程中如果直接返回给前端会存在一个问题,即参数格式、名称等可能不对应的情况,因此一般也是封装一个DTO返回给前端,但是针对小项目可以按照传统方式直接返回DO。
DTO优劣势分析
劣势
- 重复代码
- 对domain的修改可能会影响多个DTO,需同时修改这些DTO
- 需要写大量的converter、assembler的翻译代码
优势
- 解耦领域层与外部系统
- API层相对稳定
- 只返回其他系统真正需要的属性,节约网络带宽且不会暴露数据结构
- 使用代码生成工具可以有效减少开发工作量