如何用同一Java方法处理不同参数类型,减少代码冗余?
精简重复验证代码的几种方案
方案1:提取公共接口,复用验证逻辑
先定义一个包含公共字段访问方法的接口,让两个Record实现该接口:
public interface CommonRequest { CustomObjectA a(); CustomObjectB b(); } // 修改Record实现接口 public record CreateObjectRequest(CustomObjectA a, CustomObjectB b, CustomObjectC c) implements CommonRequest {} public record UpdateObjectRequest(CustomObjectA a, CustomObjectB b) implements CommonRequest {}
然后编写针对公共接口的核心验证方法,原重载方法只需调用该方法,同时按需处理Create请求的额外字段:
// 核心公共验证逻辑 private void validateCommonFields(CommonRequest request) { // 原来的完整验证逻辑,复用给两个Request // 示例:验证a非空、b的属性合法性等 } public void validateRequest(CreateObjectRequest request) { validateCommonFields(request); // 额外验证CustomObjectC c的逻辑(如果需要) if (request.c() == null) { throw new IllegalArgumentException("c cannot be null"); } } public void validateRequest(UpdateObjectRequest request) { validateCommonFields(request); // Update请求无额外字段,直接复用公共逻辑 }
方案2:提取公共参数的验证方法
如果不想引入接口,也可以直接把公共字段作为参数提取到独立方法中:
// 核心公共验证逻辑,直接接收公共字段 private void validateCommonFields(CustomObjectA a, CustomObjectB b) { // 原来的完整验证逻辑 } public void validateRequest(CreateObjectRequest request) { validateCommonFields(request.a(), request.b()); // 额外验证c字段 } public void validateRequest(UpdateObjectRequest request) { validateCommonFields(request.a(), request.b()); }
方案3:泛型结合反射(不推荐,除非必要)
如果后续可能新增大量类似Record且公共字段命名固定,可尝试反射批量获取字段,但反射会降低性能和可读性,仅适合特殊场景:
private <T> void validateCommonFields(T request) throws ReflectiveOperationException { // 通过反射获取a、b字段的访问方法 Method getA = request.getClass().getMethod("a"); Method getB = request.getClass().getMethod("b"); CustomObjectA a = (CustomObjectA) getA.invoke(request); CustomObjectB b = (CustomObjectB) getB.invoke(request); // 执行验证逻辑 } // 调用方式不变 public void validateRequest(CreateObjectRequest request) { try { validateCommonFields(request); } catch (ReflectiveOperationException e) { throw new RuntimeException("Validation failed", e); } // 额外验证c }
推荐优先使用方案1或方案2:方案1符合面向对象设计,扩展性更强;方案2更简洁,无需修改原有Record定义。
内容的提问来源于stack exchange,提问作者Antoine Mathurin
相关产品推荐
相关产品推荐

