本文介绍两种专业、可扩展的设计方式,让抽象类中的方法既能默认接收 sortdto,又能适配其他 dto 类型:一是通过统一接口抽象数据判断逻辑,二是利用方法重载实现多态支持。
本文介绍两种专业、可扩展的设计方式,让抽象类中的方法既能默认接收 sortdto,又能适配其他 dto 类型:一是通过统一接口抽象数据判断逻辑,二是利用方法重载实现多态支持。
在构建可复用的抽象基类时,常面临这样的挑战:核心业务逻辑(如根据数据状态返回 "DATOS" 或 "SINDATOS")是固定的,但具体判断依据可能分散在不同 DTO 中(如 SortDto、ReportDto、SummaryDto 等)。若强行要求所有子类都传入 SortDto,将破坏封装性与灵活性;而直接修改参数类型又违背开闭原则。以下是两种经过实践验证的解决方案:
✅ 方案一:基于接口抽象(推荐 —— 高内聚、易维护、利于测试)
定义一个轻量级契约接口,封装“是否含有效数据”的语义判断:
public interface DataStatusAware {
/**
* 判断当前 DTO 是否表示存在有效数据(即应返回 "DATOS")
*/
boolean hasData();
}
各具体 DTO 实现该接口,自行决定判定逻辑:
public class SortDto implements DataStatusAware {
private int totalNumberOfPages;
@Override
public boolean hasData() {
return totalNumberOfPages > 0;
}
// getter/setter...
}
public class ReportDto implements DataStatusAware {
private List<reportitem> items;
@Override
public boolean hasData() {
return items != null && !items.isEmpty();
}
}</reportitem>
抽象父类中统一声明为接口类型,逻辑完全解耦:
public abstract class BaseProcessor {
/**
* 根据 DTO 的数据状态返回标准化退出码
* 子类无需重写此方法,只需确保传入 DTO 实现 DataStatusAware
*/
protected String setExitStatus(DataStatusAware dto) {
return dto.hasData() ? "DATOS" : "SINDATOS";
}
}
✅ 优势:
- 符合里氏替换原则,任意 DataStatusAware 实现实例均可安全传入;
- 新增 DTO 类型只需实现接口,无需修改抽象类或子类;
- 单元测试可轻松 Mock 接口,提升可测性。
✅ 方案二:方法重载(适用于 DTO 差异大、逻辑强耦合场景)
当不同 DTO 的判断逻辑差异显著(例如需访问完全不同的字段或调用不同服务),且难以提取共性接口时,可采用重载方式:
public abstract class BaseProcessor {
protected String setExitStatus(SortDto sortDto) {
return sortDto.getTotalNumberOfPages() > 0 ? "DATOS" : "SINDATOS";
}
protected String setExitStatus(ReportDto reportDto) {
return CollectionUtils.isNotEmpty(reportDto.getItems()) ? "DATOS" : "SINDATOS";
}
protected String setExitStatus(SummaryDto summaryDto) {
return summaryDto.getRecordCount() > 100 ? "DATOS" : "SINDATOS";
}
}
⚠️ 注意事项:
- 重载方法必须在同一类中声明(不能仅靠子类覆盖实现),否则编译器无法识别多态分发;
- 若 DTO 类型过多,建议配合工厂或策略模式收敛调用入口,避免抽象类膨胀;
- 避免使用 Object + instanceof 的“类型检查式”反模式——它破坏类型安全、难以维护且无法静态校验。
? 总结建议
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| DTO 共享明确语义(如“是否有数据”) | 接口抽象(方案一) | 更具扩展性、符合 SOLID 原则、降低耦合 |
| DTO 语义迥异、逻辑高度定制化 | 方法重载(方案二) | 直观可控,避免过度抽象带来的理解成本 |
| 需动态决定 DTO 类型(如运行时配置) | 结合策略模式 + 接口抽象 | 在方案一基础上增强运行时灵活性 |
无论选择哪种方式,都应避免在抽象类中引入具体 DTO 的强依赖(如 import SortDto),优先通过接口或泛型约束来维持设计的开放性与健壮性。










