如何在考虑可伸缩性和可测试性的同时,将域实体正确转换为 DTO
我已经阅读了几篇关于将域对象转换为DTO的文章和Stackoverflow文章,并在我的代码中尝试了它们。在测试和可伸缩性方面,我总是面临一些问题。我知道以下三种将域对象转换为DTO的可能解决方案。大多数时候,我都在使用春天。
解决方案 1:服务层中用于转换的私有方法
第一种可能的解决方案是在服务层代码中创建一个小的“帮助器”方法,该方法将检索到的数据库对象转换为我的DTO对象。
@Service
public MyEntityService {
public SomeDto getEntityById(Long id){
SomeEntity dbResult = someDao.findById(id);
SomeDto dtoResult = convert(dbResult);
// ... more logic happens
return dtoResult;
}
public SomeDto convert(SomeEntity entity){
//... Object creation and using getter/setter for converting
}
}
优点:
- 易于实施
- 不需要额外的转换类 - >项目不会与实体一起爆炸
缺点:
- 测试时出现问题,就像在私有方法中使用的一样,如果对象是深度嵌套的,我必须提供足够的结果,以避免NullPointers,如果转换也溶解了嵌套结构
new SomeEntity()
when(someDao.findById(id)).thenReturn(alsoDeeplyNestedObject)
解决方案 2:DTO 中用于将域实体转换为 DTO 的其他构造函数
我的第二个解决方案是向 DTO 实体添加一个附加构造函数,以转换构造函数中的对象。
public class SomeDto {
// ... some attributes
public SomeDto(SomeEntity entity) {
this.attribute = entity.getAttribute();
// ... nesting convertion & convertion of lists and arrays
}
}
优点:
- 无需额外的转换类
- 隐藏在 DTO 实体中的转换 - >服务代码较小
缺点:
- 在服务代码中的用法,因此,由于我的嘲笑,我必须提供正确的嵌套对象结构。
new SomeDto()
someDao
解决方案3:使用Spring的转换器或任何其他外化Bean进行此转换
如果最近看到Spring出于转换原因提供了一个类:但是这个解决方案代表了每个进行转换的外部化类。使用此解决方案,我将转换器注入到我的服务代码中,当我想将域实体转换为我的DTO时,我会调用它。Converter<S, T>
优点:
- 易于测试,因为我可以在测试用例中模拟结果
- 任务分离 - >专门的类正在完成工作
缺点:
- 不会随着我的领域模型的增长而“扩展” 那么多。对于许多实体,我必须为每个新实体创建两个转换器(->将DTO实体和实体转换为DTO)
你们对我的问题有更多的解决方案吗?你们如何处理?您是否为每个新的域对象创建一个新的转换器,并且可以“生存”项目中的类数量?
提前致谢!