0

0

如何在不使用 if 判断的前提下,通过父类单个方法统一调用子类特有验证逻辑?

花韻仙語

花韻仙語

发布时间:2026-01-02 14:39:23

|

506人浏览过

|

来源于php中文网

原创

如何在不使用 if 判断的前提下,通过父类单个方法统一调用子类特有验证逻辑?

通过依赖注入将对应验证器预设到子类实例中,使 `runallvalidations()` 成为无参、类型安全、开闭原则友好的纯多态调用。

在面向对象设计中,实现“对扩展开放、对修改关闭”(Open/Closed Principle)的关键在于将行为差异下沉至具体子类,并通过多态消除运行时类型检查。针对 Vehicle 体系中不同子类需执行差异化验证(Bike 需验轮胎 + 刹车,Car 需验轮胎 + 油量)的场景,最佳实践是避免在调用处(如 main)或抽象层硬编码参数组合或条件分支,而是采用验证器预绑定 + 无参抽象方法的设计模式。

✅ 推荐方案:验证器注入 + 无参多态调用

核心思想:在创建子类实例后、调用前,主动为其注入其专属的验证器(TireValidator、BrakeValidator 或 GasValidator),使 runAllValidations() 完全解耦于外部参数,仅依赖自身已持有的依赖项。

LAIKA
LAIKA

LAIKA 是一个创意伙伴,您可以训练它像您(或您想要的任何人)一样写作。

下载

示例代码实现

// 抽象基类:仅声明契约,不暴露验证器细节
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 在调用侧做类型分发。

它将类型相关的行为决策权交还给子类自身,符合里氏替换原则与单一职责原则,同时保持了客户端代码的高度简洁与可维护性。多态不是语法糖,而是解耦复杂条件逻辑的基石。

相关专题

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

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

102

2025.08.06

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

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

231

2023.09.22

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

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

436

2024.03.01

if什么意思
if什么意思

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

738

2023.08.22

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

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

56

2025.09.05

java面向对象
java面向对象

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

49

2025.11.27

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

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

15

2025.11.27

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

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

15

2025.11.27

C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

8

2026.01.16

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 1.1万人学习

Rust 教程
Rust 教程

共28课时 | 4.4万人学习

Git 教程
Git 教程

共21课时 | 2.7万人学习

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

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