如何将实体继承关系表示为DTO以供服务层使用
实体继承关系转DTO的实现方案
方案1:保留DTO继承结构(最贴合原有业务逻辑)
- 先定义父类
AnimalDTO,抽离所有Animal共有的属性,比如id、name、age,必须额外加type字段用来区分子类类型,作为序列化/反序列化的类型识别标识 - 分别定义子类
CatDTO、DogDTO继承AnimalDTO,各自扩展独有属性,比如CatDTO可加猫专属的mewVolume,DogDTO可加狗专属的barkPitch - 服务层方法直接写为
AnimalDTO add(AnimalDTO animalDTO)即可,实际调用时可以传入CatDTO或者DogDTO的实例
补充:如果使用Jackson这类序列化框架,可以给
AnimalDTO加上@JsonTypeInfo、@JsonSubTypes注解,自动实现不同子类DTO的序列化和反序列化,不需要手动判断类型做转换。
方案2:单一扁平化DTO(适合字段差异小的简单场景)
- 只定义一个
AnimalDTO,把Animal、Cat、Dog的所有字段都放在同一个类里,用type字段标识当前实例对应猫还是狗,没有用到的字段直接传null即可 - 服务层方法直接写为
AnimalDTO add(AnimalDTO animalDTO),入参和返回值都用这一个DTO即可
优缺点:实现简单,不用维护多套DTO,但字段冗余高,子类差异字段超过3个的场景不推荐使用。
方案3:泛型封装(适合需要明确子类类型的场景)
- 定义父类
AnimalDTO<T extends AnimalDTO<T>>,子类分别写为CatDTO extends AnimalDTO<CatDTO>、DogDTO extends AnimalDTO<DogDTO> - 服务层可以保留通用方法,也可以针对不同子类写单独的重载方法,比如
CatDTO addCat(CatDTO catDTO)、DogDTO addDog(DogDTO dogDTO),满足更精细的类型校验需求。
内容的提问来源于stack exchange,提问作者toni
相关产品推荐
相关产品推荐

