如何在不使用 if 条件的前提下,通过父类单个方法调用实现子类差异化验证逻辑
发布时间 - 2026-01-02 00:00:00 点击率:次本文介绍一种基于**依赖注入 + 模板方法模式**的优雅设计:将具体验证器(如 tirevalidator、brakevalidator)在创建子类实例时预先注入,使 `runallvalidations()` 成为无参、无分支、类型安全的纯多态调用。
在面向对象设计中,当需要对不同子类执行“共性+个性”混合操作(如统一校验轮胎,再分别校验刹车或油量),又希望避免 instanceof 或参数冗余等反模式时,关键在于将“行为差异”转化为“状态差异”——即把验证器作为对象的内部状态(成员变量)而非方法参数,从而让多态方法自然解耦。
以下是一个完整、可运行的设计方案:
✅ 核心设计原则
- 职责分离:Vehicle 定义通用骨架与公共能力(如 checkTire()),不感知具体验证器类型;
- 延迟绑定:验证器通过 setter 注入(或构造器注入),确保每个子类只持有其真正需要的验证器;
- 零条件调度:runAllValidations() 在子类中直接组合已注入的验证逻辑,无需任何 if 或类型判断。
? 代码实现
// 抽象基类:定义公共状态与能力
abstract class Vehicle {
protected Tire tire;
protected TireValidator tireValidator;
public void setTireValidator(TireValidator validator) {
this.tireValidator = validator;
}
protected void checkTire() {
if (tireValidator == null) {
throw new IllegalStateException("TireValidator not set");
}
tireValidator.check(tire);
}
public abstract void runAllValidations();
}
// 子类 Bike:仅需 TireValidator + BrakeValidator
class Bike extends Vehicle {
private Brakes brakes;
private BrakeValidator brakeValidator;
public void setBrakeValidator(BrakeValidator validator) {
this.brakeValidator = validator;
}
protected void checkBrakes() {
if (brakeValidator == null) {
throw new IllegalStateException("BrakeValidator not set");
}
brakeValidator.check(brakes);
}
@Override
public void runAllValidations() {
checkTire(); // 公共逻辑
checkBrakes(); // 特有逻辑
}
}
// 子类 Car:仅需 TireValidator + GasValidator
class Car extends Vehicle {
private Gas gas;
private GasValidator gasValidator;
public void setGasValidator(GasValidator validator) {
this.gasValidator = validator;
}
protected void checkGas() {
if (gasValidator == null) {
throw new IllegalStateException("GasValidator not set");
}
gasValidator.check(gas);
}
@Override
public void runAllValidations() {
checkTire(); // 公共逻辑
checkGas(); // 特有逻辑
}
}▶️ 使用示例(主程序)
public class ValidationDemo {
public static void main(String[] args) {
// 创建验证器实例
TireValidator tireValidator = new TireValidator();
BrakeValidator brakeValidator = new BrakeValidator();
GasValidator gasValidator = new GasValidator();
// 构造具体车辆并注入其所需验证器
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); // 输出:Tire OK → Brakes OK;Tire OK → Gas OK
// 也可单独调用
car.runAllValidations();
bike.runAllValidations();
}
} ⚠️ 注意事项与进阶建议
- 空安全:示例中加入了 null 检查,生产环境推荐配合 Objects.requireNonNull() 或使用 Optional 封装验证器;
-
构造器注入更优:若验证器是必需依赖(即对象创建后必须可用),应优先使用构造器
注入替代 setter,提升不可变性与初始化安全性; - 扩展性保障:新增子类(如 Truck 需校验 Cargo 和 Axle)只需继承 Vehicle、添加对应字段/校验方法、重写 runAllValidations(),完全不影响现有代码;
- 避免“胖接口”陷阱:不采用“传入所有验证器”的方式,从根本上消除参数污染和调用方认知负担。
该方案以简洁的面向对象实践,实现了开闭原则(对扩展开放、对修改关闭)与里氏替换原则(子类可安全替换父类)的双重落地——正是多态价值的典型体现。
# go
# ai
# NULL
# if
# 面向对象
# 封装
# 多态
# 成员变量
# 父类
# 子类
# 继承
# 接口
# 对象
# 仅需
# 是一个
# 进阶
# 主程序
# 只需
# 所需
# 也可
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?
如何续费美橙建站之星域名及服务?
Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】
Laravel如何正确地在控制器和模型之间分配逻辑_Laravel代码职责分离与架构建议
历史网站制作软件,华为如何找回被删除的网站?
Laravel如何使用缓存系统提升性能_Laravel缓存驱动和应用优化方案
Laravel Telescope怎么调试_使用Laravel Telescope进行应用监控与调试
免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?
HTML5空格在Angular项目里怎么处理_Angular中空格的渲染问题【详解】
Laravel请求验证怎么写_Laravel Validator自定义表单验证规则教程
实例解析Array和String方法
laravel怎么在请求结束后执行任务(Terminable Middleware)_laravel Terminable Middleware请求结束任务执行方法
iOS发送验证码倒计时应用
Laravel如何实现RSS订阅源功能_Laravel动态生成网站XML格式订阅内容【教程】
深圳网站制作的公司有哪些,dido官方网站?
Android仿QQ列表左滑删除操作
php 三元运算符实例详细介绍
Laravel API资源(Resource)怎么用_格式化Laravel API响应的最佳实践
Laravel如何清理系统缓存命令_Laravel清除路由配置及视图缓存的方法【总结】
,交易猫的商品怎么发布到网站上去?
PythonWeb开发入门教程_Flask快速构建Web应用
如何快速生成高效建站系统源代码?
Android Socket接口实现即时通讯实例代码
ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法
哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?
Laravel的.env文件有什么用_Laravel环境变量配置与管理详解
如何生成腾讯云建站专用兑换码?
夸克浏览器网页跳转延迟怎么办 夸克浏览器跳转优化
Laravel定时任务怎么设置_Laravel Crontab调度器配置
在线制作视频的网站有哪些,电脑如何制作视频短片?
HTML透明颜色代码在Angular里怎么设置_Angular透明颜色使用指南【详解】
如何在橙子建站中快速调整背景颜色?
Laravel怎么实现验证码功能_Laravel集成验证码库防止机器人注册
如何用美橙互联一键搭建多站合一网站?
百度浏览器网页无法复制文字怎么办 百度浏览器复制修复
开心动漫网站制作软件下载,十分开心动画为何停播?
Laravel如何实现邮箱地址验证功能_Laravel邮件验证流程与配置
Android利用动画实现背景逐渐变暗
如何正确下载安装西数主机建站助手?
Laravel如何创建自定义Artisan命令?(代码示例)
香港服务器网站生成指南:免费资源整合与高速稳定配置方案
Laravel怎么实现微信登录_Laravel Socialite第三方登录集成
Laravel如何创建自定义中间件?(Middleware代码示例)
使用豆包 AI 辅助进行简单网页 HTML 结构设计
如何在建站之星网店版论坛获取技术支持?
如何在腾讯云服务器上快速搭建个人网站?
胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?
公司网站制作价格怎么算,公司办个官网需要多少钱?
如何快速搭建二级域名独立网站?
香港服务器建站指南:免备案优势与SEO优化技巧全解析


注入替代 setter,提升不可变性与初始化安全性;