0

0

如何通过面向对象多态实现无条件分支的统一验证调用

花韻仙語

花韻仙語

发布时间:2026-01-02 15:09:08

|

675人浏览过

|

来源于php中文网

原创

如何通过面向对象多态实现无条件分支的统一验证调用

本文介绍一种基于依赖注入与模板方法模式的设计方案:将各类校验器(如轮胎、刹车、油量)在对象创建后预先注入子类实例,使抽象父类 `vehicle` 的 `runallvalidations()` 方法可无参数、无 `if` 分支地完成类型专属的完整校验流程。

在面向对象设计中,避免运行时类型判断(如 instanceof 或 if-else 链)的关键在于将“决策权”前移至对象构建阶段,而非执行阶段。本方案摒弃了“向通用方法传入所有可能校验器”的冗余方式,也规避了显式类型检查的坏味道,转而采用 “校验器注入 + 模板方法” 的组合策略,既保持接口统一性,又确保行为专一性。

✅ 核心设计思想

  • 职责分离:Vehicle 定义统一入口 runAllValidations(),但不参与具体校验逻辑;各子类负责声明自身所需的校验器字段,并在 runAllValidations() 中按需调用对应 checkXxx() 方法。
  • 依赖前置注入:校验器(TireValidator、BrakeValidator、GasValidator)不在调用时传入,而是在对象初始化后通过 setXxxValidator() 显式注入——这使校验逻辑完全解耦于调用上下文。
  • 多态驱动执行:main 中只需持有 Vehicle 类型引用,调用 runAllValidations() 即可自动触发子类定制化逻辑,真正实现“一个接口,多种实现”。

? 完整代码示例

// 抽象基类:定义公共校验能力与统一入口
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 (brakeValidator != 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()
}

⚠️ 注意事项与最佳实践

  • 空校验防护:示例中在 checkXxx() 内添加了 null 检查并抛出明确异常,避免静默失败;生产环境建议结合 Objects.requireNonNull() 或构造器强制注入(如使用 Spring 的 @RequiredArgsConstructor)进一步强化契约。
  • 扩展性友好:新增车辆类型(如 Truck 需校验载重与灯光)只需继承 Vehicle、注入对应校验器、重写 runAllValidations(),无需修改任何现有类或条件逻辑
  • 替代进阶方案:若校验器生命周期复杂(如需复用、代理、AOP 增强),可考虑引入 ValidatorRegistry 或依赖注入框架(如 Spring)管理校验器 Bean,再通过 @Autowired 自动装配到子类中,进一步降低手动注入成本。

该方案以简洁、可读、可维护的方式,完美践行了 “开闭原则”“里氏替换原则”,是消除类型判断、提升多态价值的经典实践。

Amazon Nova
Amazon Nova

亚马逊云科技(AWS)推出的一系列生成式AI基础模型

下载

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

98

2025.08.06

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

229

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

434

2024.03.01

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

713

2023.08.22

go语言 面向对象
go语言 面向对象

本专题整合了go语言面向对象相关内容,阅读专题下面的文章了解更多详细内容。

54

2025.09.05

java面向对象
java面向对象

本专题整合了java面向对象相关内容,阅读专题下面的文章了解更多详细内容。

47

2025.11.27

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

15

2025.11.27

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

15

2025.11.27

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

74

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号