
本文介绍一种基于**依赖注入 + 模板方法模式**的优雅设计:将具体验证器(如 tirevalidator、brakevalidator)在创建子类实例时预先注入,使 `runallvalidations()` 成为无参、无分支、类型安全的纯多态调用。
在面向对象设计中,当需要对不同子类执行“共性+个性”混合操作(如统一校验轮胎,再分别校验刹车或油量),又希望避免 instanceof 或参数冗余等反模式时,关键在于将“行为差异”转化为“状态差异”——即把验证器作为对象的内部状态(成员变量)而非方法参数,从而让多态方法自然解耦。
以下是一个完整、可运行的设计方案:
✅ 核心设计原则
- 职责分离:Vehicle 定义通用骨架与公共能力(如 checkTire()),不感知具体验证器类型;
- 延迟绑定:验证器通过 setter 注入(或构造器注入),确保每个子类只持有其真正需要的验证器;
- 零条件调度:runAllValidations() 在子类中直接组合已注入的验证逻辑,无需任何 if 或类型判断。
? 代码实现
// 抽象基类:定义公共状态与能力
abstract class Vehicle {
protected Tire tire;
protected TireValidator tireValidator;
public void setTireValidator(TireValidator validator) {
this.tireValidator = validator;
}
protected void checkTire() {
if (tireValidator == null) {
throw new IllegalStateException("TireValidator not set");
}
tireValidator.check(tire);
}
public abstract void runAllValidations();
}
// 子类 Bike:仅需 TireValidator + BrakeValidator
class Bike extends Vehicle {
private Brakes brakes;
private BrakeValidator brakeValidator;
public void setBrakeValidator(BrakeValidator validator) {
this.brakeValidator = validator;
}
protected void checkBrakes() {
if (brakeValidator == null) {
throw new IllegalStateException("BrakeValidator not set");
}
brakeValidator.check(brakes);
}
@Override
public void runAllValidations() {
checkTire(); // 公共逻辑
checkBrakes(); // 特有逻辑
}
}
// 子类 Car:仅需 TireValidator + GasValidator
class Car extends Vehicle {
private Gas gas;
private GasValidator gasValidator;
public void setGasValidator(GasValidator validator) {
this.gasValidator = validator;
}
protected void checkGas() {
if (gasValidator == null) {
throw new IllegalStateException("GasValidator not set");
}
gasValidator.check(gas);
}
@Override
public void runAllValidations() {
checkTire(); // 公共逻辑
checkGas(); // 特有逻辑
}
}▶️ 使用示例(主程序)
public class ValidationDemo {
public static void main(String[] args) {
// 创建验证器实例
TireValidator tireValidator = new TireValidator();
BrakeValidator brakeValidator = new BrakeValidator();
GasValidator gasValidator = new GasValidator();
// 构造具体车辆并注入其所需验证器
Bike bike = new Bike();
bike.setTireValidator(tireValidator);
bike.setBrakeValidator(brakeValidator);
Car car = new Car();
car.setTireValidator(tireValidator);
car.setGasValidator(gasValidator);
// ✅ 统一调用 —— 完全多态,无 if,无冗余参数
List vehicles = List.of(bike, car);
vehicles.forEach(Vehicle::runAllValidations); // 输出:Tire OK → Brakes OK;Tire OK → Gas OK
// 也可单独调用
car.runAllValidations();
bike.runAllValidations();
}
} ⚠️ 注意事项与进阶建议
- 空安全:示例中加入了 null 检查,生产环境推荐配合 Objects.requireNonNull() 或使用 Optional 封装验证器;
- 构造器注入更优:若验证器是必需依赖(即对象创建后必须可用),应优先使用构造器注入替代 setter,提升不可变性与初始化安全性;
- 扩展性保障:新增子类(如 Truck 需校验 Cargo 和 Axle)只需继承 Vehicle、添加对应字段/校验方法、重写 runAllValidations(),完全不影响现有代码;
- 避免“胖接口”陷阱:不采用“传入所有验证器”的方式,从根本上消除参数污染和调用方认知负担。
该方案以简洁的面向对象实践,实现了开闭原则(对扩展开放、对修改关闭)与里氏替换原则(子类可安全替换父类)的双重落地——正是多态价值的典型体现。










