0

0

Java通用方法优化:利用抽象父类处理相似请求对象

碧海醫心

碧海醫心

发布时间:2025-09-23 10:15:02

|

445人浏览过

|

来源于php中文网

原创

Java通用方法优化:利用抽象父类处理相似请求对象

本文探讨了在Java中,当多个请求对象具有相似结构且需要应用相同业务逻辑(如验证)时,如何通过引入抽象父类来消除代码冗余。通过将共享字段和行为上移至抽象父类,并利用多态性,可以显著减少方法重载,提升代码的可维护性、可扩展性和可读性,从而避免重复编写相同的验证逻辑。

优化相似请求对象的通用处理逻辑

软件开发中,我们经常会遇到这样的场景:多个数据传输对象(dto)或请求对象在结构上高度相似,并且需要经过相同的业务逻辑处理,例如数据验证。如果为每个相似的请求对象都编写一个独立的处理方法,即使这些方法的内部逻辑完全相同,也会导致大量的代码重复,降低代码的可维护性和可读性。

考虑以下两个Java record 类型,它们分别用于创建和更新对象:

public record CreateObjectRequest (
    CustomObjectA a,
    CustomObjectB b,
    CustomObjectC c
) {}

public record UpdateObjectRequest (
    CustomObjectA a,
    CustomObjectB b
) {}

如果我们需要对这两个请求对象执行相同的验证逻辑,一个常见的做法是为它们分别创建重载的验证方法:

public class RequestValidator {
    public void validateRequest(CreateObjectRequest createObjectRequest) {
        // 大量相同的验证逻辑...
        System.out.println("Validating CreateObjectRequest...");
        // 示例:检查a和b是否为空
        if (createObjectRequest.a() == null) {
            throw new IllegalArgumentException("CustomObjectA cannot be null for CreateObjectRequest.");
        }
        if (createObjectRequest.b() == null) {
            throw new IllegalArgumentException("CustomObjectB cannot be null for CreateObjectRequest.");
        }
        // ... 其他验证
    }

    public void validateRequest(UpdateObjectRequest updateObjectRequest) {
        // 同样大量的验证逻辑...
        System.out.println("Validating UpdateObjectRequest...");
        // 示例:检查a和b是否为空
        if (updateObjectRequest.a() == null) {
            throw new IllegalArgumentException("CustomObjectA cannot be null for UpdateObjectRequest.");
        }
        if (updateObjectRequest.b() == null) {
            throw new IllegalArgumentException("CustomObjectB cannot be null for UpdateObjectRequest.");
        }
        // ... 其他验证
    }
}

这种方法虽然功能上可行,但显然存在代码冗余。当验证逻辑变得复杂或需要修改时,必须在多个地方进行同步更新,极易出错。

利用抽象父类实现代码复用

为了解决上述问题,我们可以利用Java的面向对象特性,特别是抽象类和继承,来消除这种冗余。核心思想是识别出所有相似请求对象共有的字段和行为,并将它们抽象到一个共同的父类中。

立即学习Java免费学习笔记(深入)”;

1. 定义抽象父类

首先,创建一个抽象父类,例如 ObjectRequest,它包含所有子请求类型共享的字段。

// 假设 CustomObjectA 和 CustomObjectB 的基类或接口是 CustomObject
public abstract class ObjectRequest {
    protected CustomObject a;
    protected CustomObject b;

    // 构造函数、getter/setter(如果需要)
    public CustomObject getA() {
        return a;
    }

    public CustomObject getB() {
        return b;
    }
}

注意事项:

  • 这里将 CustomObjectA 和 CustomObjectB 统一为 CustomObject,前提是它们具有共同的父类或接口,或者我们可以通过类型擦除来处理。在实际应用中,如果 CustomObjectA 和 CustomObjectB 是完全独立的类型但只是字段名相同,则需要考虑更复杂的泛型或接口方案。但根据问题描述,它们是“同样的字段”,暗示可以抽象。
  • 字段声明为 protected 或 public,以便子类可以访问或通过 getter 方法提供访问。

2. 子类继承抽象父类

接下来,让具体的请求对象(如 CreateObjectRequest 和 UpdateObjectRequest)继承这个抽象父类。由于Java record 类型不能直接继承类,我们可以将 record 改为普通的 class,或者在 record 内部通过组合来引用父类的逻辑(但这样就失去了继承带来的多态便利)。为了实现继承带来的多态性,我们通常会选择将 record 转换为普通 class。

Bika.ai
Bika.ai

打造您的AI智能体员工团队

下载
// CreateObjectRequest 继承 ObjectRequest
public class CreateObjectRequest extends ObjectRequest {
    private CustomObjectC c; // CreateObjectRequest 特有的字段

    public CreateObjectRequest(CustomObjectA a, CustomObjectB b, CustomObjectC c) {
        this.a = a; // 从父类继承的字段
        this.b = b; // 从父类继承的字段
        this.c = c;
    }

    public CustomObjectC getC() {
        return c;
    }
}

// UpdateObjectRequest 继承 ObjectRequest
public class UpdateObjectRequest extends ObjectRequest {
    // UpdateObjectRequest 没有特有的字段,或者有其他特有字段
    public UpdateObjectRequest(CustomObjectA a, CustomObjectB b) {
        this.a = a; // 从父类继承的字段
        this.b = b; // 从父类继承的字段
    }
}

注意: 这里的 CustomObjectA 和 CustomObjectB 类型在 ObjectRequest 中被统一为 CustomObject。如果 CustomObjectA 和 CustomObjectB 本身不是 CustomObject 的子类,但它们都具有某些共同的属性,那么 ObjectRequest 中的 a 和 b 可以声明为它们的共同接口或基类类型。为了简化,这里假设 CustomObjectA 和 CustomObjectB 都可以被 CustomObject 类型引用。

3. 重构通用处理方法

现在,验证方法只需要接受抽象父类 ObjectRequest 作为参数。通过多态性,这个方法就可以处理所有继承自 ObjectRequest 的子类实例。

public class RequestValidator {
    public void validateRequest(ObjectRequest objectRequest) {
        // 通用的验证逻辑,现在只需要编写一次
        System.out.println("Validating generic ObjectRequest...");

        // 访问父类中的共享字段
        if (objectRequest.getA() == null) {
            throw new IllegalArgumentException("CustomObjectA cannot be null.");
        }
        if (objectRequest.getB() == null) {
            throw new IllegalArgumentException("CustomObjectB cannot be null.");
        }

        // 如果需要针对特定子类进行额外验证,可以使用 instanceof
        if (objectRequest instanceof CreateObjectRequest createRequest) {
            System.out.println("Performing CreateObjectRequest specific validation.");
            if (createRequest.getC() == null) {
                throw new IllegalArgumentException("CustomObjectC cannot be null for CreateObjectRequest.");
            }
        } else if (objectRequest instanceof UpdateObjectRequest updateRequest) {
            System.out.println("Performing UpdateObjectRequest specific validation.");
            // 针对 UpdateObjectRequest 的特有验证
        }
        // ... 其他通用验证
    }
}

通过这种方式,我们成功地将重复的验证逻辑集中到一个方法中。当需要修改或扩展通用验证逻辑时,只需修改 validateRequest(ObjectRequest objectRequest) 方法即可,大大提高了代码的可维护性和可扩展性。

总结与最佳实践

利用抽象父类来优化通用方法是Java中一种强大的代码复用模式。它适用于以下场景:

  • 多个类共享大量相同的字段和行为:这些类在概念上属于同一类事物,但有各自的特有属性。
  • 需要对这些相似类执行相同的操作:例如验证、序列化、转换等。

优点:

  • 减少代码冗余:避免重复编写相同的业务逻辑。
  • 提高可维护性:逻辑修改只需在一个地方进行。
  • 增强可扩展性:新增的相似请求类型只需继承抽象父类,即可自动获得通用处理能力。
  • 改善可读性:代码结构更清晰,意图表达更明确。

注意事项:

  • 过度抽象:如果类之间的共同点非常少,或者强行将不相关的类抽象到一起,可能会导致设计过于复杂,反而降低可读性。
  • 继承的局限性:Java是单继承语言,如果一个类已经继承了其他类,就不能再通过继承这种方式来复用通用逻辑。此时可以考虑接口结合默认方法、组合模式或泛型等其他设计模式。
  • record 类型的限制:record 类型在Java 16+中引入,其设计目标是作为不可变的数据载体,不能继承其他类(但可以实现接口)。因此,如果需要利用继承实现多态,可能需要将 record 转换为传统的 class。

通过合理运用抽象和继承,开发者可以编写出更优雅、更健壮、更易于维护的Java代码。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
go语言 面向对象
go语言 面向对象

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

56

2025.09.05

java面向对象
java面向对象

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

52

2025.11.27

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

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

15

2025.11.27

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

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

15

2025.11.27

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

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

15

2025.11.27

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1126

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

192

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1642

2025.12.29

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

158

2026.01.28

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3万人学习

C# 教程
C# 教程

共94课时 | 7.8万人学习

Java 教程
Java 教程

共578课时 | 52.7万人学习

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

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