You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 22:20:39