
在软件开发中,我们经常会遇到这样的场景:多个数据传输对象(dtos)或记录(records)在结构上存在高度相似性,它们可能共享大部分字段,但又因业务需求略有差异。例如,一个创建请求对象(createobjectrequest)和一个更新请求对象(updateobjectrequest),它们可能都包含 customobjecta 和 customobjectb 等字段,但 createobjectrequest 可能额外包含 customobjectc。当需要对这些对象执行相同的验证逻辑时,一种直观但低效的做法是为每种类型定义一个重载方法:
public record CreateObjectRequest (
CustomObjectA a,
CustomObjectB b,
CustomObjectC c
) {}
public record UpdateObjectRequest (
CustomObjectA a,
CustomObjectB b
) {}
// 冗余的验证方法
public void validateRequest(CreateObjectRequest createObjectRequest) {
// 包含大量相同的验证逻辑
// ...
}
public void validateRequest(UpdateObjectRequest updateObjectRequest) {
// 几乎完全相同的验证逻辑
// ...
}这种方法虽然功能上可行,但会导致大量的代码重复("long body"),降低了代码的可维护性。一旦验证逻辑需要修改,开发者必须在多个地方进行同步更新,极易引入错误。
为了解决上述代码冗余问题,我们可以利用Java的面向对象特性——抽象类和多态。核心思想是识别出所有相关对象(如 CreateObjectRequest 和 UpdateObjectRequest)的共同字段,并将这些共同字段抽象到一个父类中。然后,让所有具体请求类继承这个抽象父类。这样,验证方法就可以统一接收这个抽象父类作为参数,从而实现一套逻辑处理多种类型。
首先,创建一个抽象父类,例如 ObjectRequest,它包含所有子类共有的字段。如果这些字段本身也是自定义对象,也应确保它们被正确定义。
// 假设 CustomObjectA, CustomObjectB, CustomObjectC 已定义
public class CustomObjectA {}
public class CustomObjectB {}
public class CustomObjectC {}
public abstract class ObjectRequest {
// 包含所有子类共有的字段
protected CustomObjectA a;
protected CustomObjectB b;
// 构造函数、getter/setter(如果需要)
public ObjectRequest(CustomObjectA a, CustomObjectB b) {
this.a = a;
this.b = b;
}
public CustomObjectA getA() { return a; }
public CustomObjectB getB() { return b; }
// ... 其他通用方法
}接下来,让 CreateObjectRequest 和 UpdateObjectRequest 不再是独立的记录,而是继承 ObjectRequest。它们可以根据自身特有的字段进行扩展。
立即学习“Java免费学习笔记(深入)”;
// CreateObjectRequest 继承 ObjectRequest,并添加特有字段
public class CreateObjectRequest extends ObjectRequest {
private CustomObjectC c;
public CreateObjectRequest(CustomObjectA a, CustomObjectB b, CustomObjectC c) {
super(a, b);
this.c = c;
}
public CustomObjectC getC() { return c; }
// ...
}
// UpdateObjectRequest 继承 ObjectRequest,如果它没有特有字段,可以保持简洁
public class UpdateObjectRequest extends ObjectRequest {
public UpdateObjectRequest(CustomObjectA a, CustomObjectB b) {
super(a, b);
}
// ...
}注意:Java Records 默认是 final 的,不能被继承。如果需要使用继承,则不能使用 record 关键字,而应使用传统的 class。上述示例已调整为 class。
现在,验证方法只需要接受抽象父类 ObjectRequest 作为参数。由于多态性,无论传入的是 CreateObjectRequest 还是 UpdateObjectRequest 的实例,都可以被这个方法处理。
public class RequestValidator {
public void validateRequest(ObjectRequest 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) {
if (createRequest.getC() == null) {
throw new IllegalArgumentException("CustomObjectC is required for creation.");
}
// ... 针对 CreateObjectRequest 的特有验证
}
// else if (objectRequest instanceof UpdateObjectRequest updateRequest) { ... }
}
}注意事项:
通过引入抽象父类并利用Java的多态机制,我们可以优雅地解决不同参数类型但逻辑相同的通用方法所导致的冗余问题。这种方法不仅减少了代码重复,提高了可维护性和可扩展性,也促使我们遵循更好的面向对象设计原则。在设计系统时,识别并抽象出对象间的共同特性是构建健壮、灵活代码的关键一步。
以上就是Java中利用抽象父类优化多类型参数通用方法验证的策略的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号