
通过依赖注入将对应验证器预设到子类实例中,使 `runallvalidations()` 成为无参、类型安全、开闭原则友好的纯多态调用。
在面向对象设计中,实现“对扩展开放、对修改关闭”(Open/Closed Principle)的关键在于将行为差异下沉至具体子类,并通过多态消除运行时类型检查。针对 Vehicle 体系中不同子类需执行差异化验证(Bike 需验轮胎 + 刹车,Car 需验轮胎 + 油量)的场景,最佳实践是避免在调用处(如 main)或抽象层硬编码参数组合或条件分支,而是采用验证器预绑定 + 无参抽象方法的设计模式。
✅ 推荐方案:验证器注入 + 无参多态调用
核心思想:在创建子类实例后、调用前,主动为其注入其专属的验证器(TireValidator、BrakeValidator 或 GasValidator),使 runAllValidations() 完全解耦于外部参数,仅依赖自身已持有的依赖项。
示例代码实现
// 抽象基类:仅声明契约,不暴露验证器细节
abstract class Vehicle {
protected Tire tire;
// 公共验证逻辑(由子类复用)
protected void checkTire(TireValidator validator) {
if (validator != null) validator.check(tire);
}
// 统一入口:无参、无条件、纯多态
public abstract void runAllValidations();
}
// Bike:持有自身所需验证器引用
class Bike extends Vehicle {
private Brakes brakes;
private TireValidator tireValidator;
private BrakeValidator brakeValidator;
public void setTireValidator(TireValidator validator) {
this.tireValidator = validator;
}
public void setBrakeValidator(BrakeValidator validator) {
this.brakeValidator = validator;
}
@Override
public void runAllValidations() {
checkTire(tireValidator); // 复用父类公共逻辑
if (brakeValidator != null) {
brakeValidator.check(brakes);
}
}
}
// Car:同理,按需绑定
class Car extends Vehicle {
private Gas gas;
private TireValidator tireValidator;
private GasValidator gasValidator;
public void setTireValidator(TireValidator validator) {
this.tireValidator = validator;
}
public void setGasValidator(GasValidator validator) {
this.gasValidator = validator;
}
@Override
public void runAllValidations() {
checkTire(tireValidator);
if (gasValidator != null) {
gasValidator.check(gas);
}
}
}调用端(main)简洁、类型安全、无 if
public static void main(String[] args) {
// 创建验证器
TireValidator tireValidator = new TireValidatorImpl();
BrakeValidator brakeValidator = new BrakeValidatorImpl();
GasValidator gasValidator = new GasValidatorImpl();
// 创建并注入依赖
Bike bike = new Bike(/*...*/);
bike.setTireValidator(tireValidator);
bike.setBrakeValidator(brakeValidator);
Car car = new Car(/*...*/);
car.setTireValidator(tireValidator);
car.setGasValidator(gasValidator);
// ✅ 统一调用 —— 无需传参、无需 instanceof、无需 if
List vehicles = List.of(bike, car);
vehicles.forEach(Vehicle::runAllValidations); // 多态自动分发
// 或单独调用
bike.runAllValidations(); // → checkTire + checkBrakes
car.runAllValidations(); // → checkTire + checkGas
} ⚠️ 注意事项与增强建议
- 空值防护:示例中已加入 if (validator != null),实际项目中可结合 Objects.requireNonNull() 或使用 Optional 显式表达依赖可选性。
- 构造时注入更优:为提升不可变性与线程安全性,推荐将验证器通过构造函数注入(如 new Bike(tireValidator, brakeValidator)),而非 setter —— 这进一步杜绝了“未配置即调用”的风险。
- 接口细化(进阶):若验证器种类持续增长,可定义标记接口(如 TireValidatable, BrakeValidatable),配合 instanceof 在工厂/构建器中 使用(非业务逻辑层),实现更灵活的组合装配。
- Spring 等框架支持:在 DI 容器环境中,可直接通过 @Autowired 或构造注入自动完成验证器绑定,彻底消除手动 setXxxValidator() 调用。
✅ 总结
该方案彻底规避了两种反模式:
❌ 不再传递冗余参数(如向 Bike 传 GasValidator);
❌ 不再使用 instanceof / if-else 在调用侧做类型分发。
它将类型相关的行为决策权交还给子类自身,符合里氏替换原则与单一职责原则,同时保持了客户端代码的高度简洁与可维护性。多态不是语法糖,而是解耦复杂条件逻辑的基石。









