本文介绍一种基于依赖注入与模板方法模式的设计方案:将各类校验器(如轮胎、刹车、油量)在对象创建后预先注入子类实例,使抽象父类 `vehicle` 的 `runallvalidations()` 方法可无参数、无 `if` 分支地完成类型专属的完整校验流程。
在面向对象设计中,避免运行时类型判断(如 instanceof 或 if-else 链)的关键在于将“决策权”前移至对象构建阶段,而非执行阶段。本方案摒弃了“向通用方法传入所有可能校验器”的冗余方式,也规避了显式类型检查的坏味道,转而采用 “校验器注入 + 模板方法” 的组合策略,既保持接口统一性,又确保行为专一性。
// 抽象基类:定义公共校验能力与统一入口
abstract class Vehicle {
protected Tire tire;
protected TireValidator tireValidator;
public void setTireValidator(TireValidator tireValidator) {
this.tireValidator = tireValidator;
}
protected void checkTire() {
if (tireValidator != null) {
tireValidator.check(tire);
} else {
throw new IllegalStateException("TireValidator not set for " + getClass().getSimpleName());
}
}
public abstract void runAllValidations();
}
// 子类 Bike:仅关注轮胎 + 刹车
class Bike extends Vehicle {
private Brakes brakes;
private BrakeValidator brakeValidator;
public void setBrakeValidator(BrakeValidator brakeValidator) {
this.brakeValidator = brakeValidator;
}
protected void checkBrakes() {
if (bra
keValidator != null) {
brakeValidator.check(brakes);
} else {
throw new IllegalStateException("BrakeValidator not set for Bike");
}
}
@Override
public void runAllValidations() {
checkTire(); // 复用父类逻辑
checkBrakes(); // 扩展自身逻辑
}
}
// 子类 Car:仅关注轮胎 + 油量
class Car extends Vehicle {
private Gas gas;
private GasValidator gasValidator;
public void setGasValidator(GasValidator gasValidator) {
this.gasValidator = gasValidator;
}
protected void checkGas() {
if (gasValidator != null) {
gasValidator.check(gas);
} else {
throw new IllegalStateException("GasValidator not set for Car");
}
}
@Override
public void runAllValidations() {
checkTire(); // 复用父类逻辑
checkGas(); // 扩展自身逻辑
}
}public static void main(String[] args) {
// 实例化校验器(假设已实现)
TireValidator tireValidator = new DefaultTireValidator();
BrakeValidator brakeValidator = new DefaultBrakeValidator();
GasValidator gasValidator = new DefaultGasValidator();
// 构建具体车辆并注入其专属校验器
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); // ✅ 多态自动分发
// 或单独调用
car.runAllValidations(); // → checkTire() + checkGas()
bike.runAllValidations(); // → checkTire() + checkBrakes()
} 该方案以简洁、可读、可维护的方式,完美践行了 “开闭原则” 与 “里氏替换原则”,是消除类型判断、提升多态价值的经典实践。