如何在考虑可伸缩性和可测试性的同时,将域实体正确转换为 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)
 
你们对我的问题有更多的解决方案吗?你们如何处理?您是否为每个新的域对象创建一个新的转换器,并且可以“生存”项目中的类数量?
提前致谢!