无需if条件,通过超类单方法调用子类带不同参数的验证方法
最优设计方案:使用访问者模式
这个问题的核心是要在不传递冗余参数、不做类型判断的前提下,让不同子类执行各自的专属验证逻辑,访问者模式刚好能完美解决这个问题——它通过多态让子类主动匹配对应的处理逻辑,完全规避冗余和条件判断。
步骤1:定义访问者接口
先创建一个访问者接口,专门处理不同Vehicle子类的验证逻辑:
interface VehicleValidatorVisitor { void visit(Bike bike); void visit(Car car); }
步骤2:修改抽象类Vehicle
给Vehicle添加accept方法,让子类实现该方法来接收访问者;同时实现runAllValidations方法,把验证逻辑委托给访问者:
abstract class Vehicle { Tire tire; // 公共方法 void checkTire(TireValidator tireValidator) { tireValidator.check(tire); } // 新增accept方法,接收访问者 abstract void accept(VehicleValidatorVisitor visitor); // 实现runAllValidations,委托给访问者 void runAllValidations(VehicleValidatorVisitor visitor) { accept(visitor); } }
步骤3:实现具体访问者类
创建一个持有所有验证器的访问者实现类,在对应方法里调用子类的专属验证+公共验证:
class DefaultVehicleValidatorVisitor implements VehicleValidatorVisitor { private final TireValidator tireValidator; private final BrakeValidator brakeValidator; private final GasValidator gasValidator; // 构造方法注入所有验证器 public DefaultVehicleValidatorVisitor(TireValidator tireValidator, BrakeValidator brakeValidator, GasValidator gasValidator) { this.tireValidator = tireValidator; this.brakeValidator = brakeValidator; this.gasValidator = gasValidator; } @Override public void visit(Bike bike) { // 执行公共轮胎验证 + Bike专属刹车验证 bike.checkTire(tireValidator); bike.checkBrakes(brakeValidator); } @Override public void visit(Car car) { // 执行公共轮胎验证 + Car专属油量验证 car.checkTire(tireValidator); car.checkGas(gasValidator); } }
步骤4:修改Bike和Car类,实现accept方法
让子类主动调用访问者的对应visit方法,完成多态匹配:
class Bike extends Vehicle { Brakes brakes; void checkBrakes(BrakeValidator brakeValidator) { brakeValidator.check(brakes); } @Override void accept(VehicleValidatorVisitor visitor) { visitor.visit(this); } }
class Car extends Vehicle { Gas gas; void checkGas(GasValidator gasValidator) { gasValidator.check(gas); } @Override void accept(VehicleValidatorVisitor visitor) { visitor.visit(this); } }
步骤5:主类调用
现在主类只需要创建访问者实例,传入所有验证器,然后直接调用Vehicle的runAllValidations即可:
void main() { TireValidator tireValidator = new TireValidator(); BrakeValidator brakeValidator = new BrakeValidator(); GasValidator gasValidator = new GasValidator(); // 创建访问者实例 VehicleValidatorVisitor visitor = new DefaultVehicleValidatorVisitor(tireValidator, brakeValidator, gasValidator); Vehicle car = new Car(...); Vehicle bike = new Bike(...); // 统一调用,无需判断类型,无冗余参数 car.runAllValidations(visitor); bike.runAllValidations(visitor); }
方案优势
- 完全没有冗余参数:访问者只会在对应
visit方法里用到需要的验证器,不会传递无用参数 - 无任何
if/instanceof判断:所有逻辑都通过多态自动匹配,符合面向对象设计原则 - 扩展性强:后续新增
Vehicle子类(比如Truck),只需要给访问者接口加一个visit(Truck truck)方法,再实现Truck的accept方法即可,无需修改原有代码,符合开闭原则
内容的提问来源于stack exchange,提问作者Pardhu
相关产品推荐
相关产品推荐

