Java校验模块案例如何复用

wen java案例 26

本文目录导读:

Java校验模块案例如何复用

  1. 核心复用思路:分层解耦 + 策略化
  2. 企业级最佳实践:组合使用

在Java中,校验模块的复用是提升开发效率和代码质量的关键,以下我会从设计模式实际案例两个维度,为你提供几种成熟的复用方案。

核心复用思路:分层解耦 + 策略化

基于注解的校验(JSR-380 / Bean Validation)

这是最标准的复用方式,适合简单字段校验

// 1. 定义可复用的校验注解
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PhoneValidator.class)
public @interface ValidPhone {
    String message() default "手机号格式错误";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
// 2. 校验逻辑实现(可复用)
public class PhoneValidator implements ConstraintValidator<ValidPhone, String> {
    private static final String PHONE_REGEX = "^1[3-9]\\d{9}$";
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null || value.isEmpty()) {
            return true; // 允许空值,用@NotNull配合
        }
        return value.matches(PHONE_REGEX);
    }
}
// 3. 在任意实体中复用
public class UserDTO {
    @ValidPhone
    private String phone;
    @ValidPhone(groups = {Admin.class}) // 分组校验
    private String adminPhone;
}

复用方式:一个注解全局使用,业务代码无需重复写if判断。


策略模式 + 工厂模式(复杂业务校验)

当校验规则复杂且经常变动时,使用策略模式实现可插拔的校验单元。

// 1. 定义校验策略接口
public interface ValidationStrategy<T> {
    ValidationResult validate(T target);
}
// 2. 实现具体策略(每个策略独立可复用)
public class OrderAmountStrategy implements ValidationStrategy<Order> {
    @Override
    public ValidationResult validate(Order order) {
        if (order.getAmount() <= 0) {
            return ValidationResult.fail("订单金额必须大于0");
        }
        return ValidationResult.success();
    }
}
public class UserAgeStrategy implements ValidationStrategy<User> {
    @Override
    public ValidationResult validate(User user) {
        if (user.getAge() < 0 || user.getAge() > 150) {
            return ValidationResult.fail("年龄不合法");
        }
        return ValidationResult.success();
    }
}
// 3. 策略工厂(管理校验规则组合)
public class ValidationFactory {
    private static final Map<String, List<ValidationStrategy>> rules = new HashMap<>();
    static {
        rules.put("order", Arrays.asList(new OrderAmountStrategy(), 
                                         new OrderStatusStrategy()));
        rules.put("user", Arrays.asList(new UserAgeStrategy(), 
                                        new UserNameStrategy()));
    }
    public static List<ValidationStrategy> getStrategies(String type) {
        return rules.getOrDefault(type, Collections.emptyList());
    }
}
// 4. 校验执行器(统一复用入口)
public class ValidationExecutor {
    public static <T> ValidationResult execute(String type, T target) {
        List<ValidationStrategy> strategies = ValidationFactory.getStrategies(type);
        for (ValidationStrategy strategy : strategies) {
            ValidationResult result = strategy.validate(target);
            if (result.isFail()) {
                return result;
            }
        }
        return ValidationResult.success();
    }
}
// 使用示例
Order order = new Order();
ValidationResult result = ValidationExecutor.execute("order", order);

复用方式:任意业务逻辑只要调用ValidationExecutor.execute("user", user)即可复用所有用户校验规则。


责任链模式(流水线式校验)

适合需要顺序执行可动态组装的场景。

// 1. 抽象校验节点
public abstract class ValidationHandler {
    protected ValidationHandler next;
    public ValidationHandler setNext(ValidationHandler next) {
        this.next = next;
        return next;
    }
    public abstract boolean handle(Request request);
    protected boolean handleNext(Request request) {
        if (next == null) return true;
        return next.handle(request);
    }
}
// 2. 具体节点(可独立复用)
public class TokenValidationHandler extends ValidationHandler {
    @Override
    public boolean handle(Request request) {
        if (request.getToken() == null || request.getToken().isEmpty()) {
            System.out.println("Token校验失败");
            return false;
        }
        System.out.println("Token校验通过");
        return handleNext(request);
    }
}
public class PermissionValidationHandler extends ValidationHandler {
    @Override
    public boolean handle(Request request) {
        if (!"admin".equals(request.getRole())) {
            System.out.println("权限不足");
            return false;
        }
        System.out.println("权限校验通过");
        return handleNext(request);
    }
}
// 3. 动态组装校验链(复用点)
public class ValidationChainBuilder {
    public static ValidationHandler buildDefaultChain() {
        ValidationHandler tokenHandler = new TokenValidationHandler();
        ValidationHandler permissionHandler = new PermissionValidationHandler();
        tokenHandler.setNext(permissionHandler);
        return tokenHandler; // 返回链头
    }
}
// 使用
Request request = new Request();
ValidationHandler chain = ValidationChainBuilder.buildDefaultChain();
boolean pass = chain.handle(request);

复用方式:通过buildDefaultChain()轻松组装可复用的校验流水线,也可通过配置文件动态修改。


模板方法模式(固定校验骨架)

适合校验流程通用具体校验逻辑不同的场景。

// 1. 抽象校验模板
public abstract class AbstractValidator<T> {
    // 模板方法:定义校验的固定骨架
    public final ValidationResult validate(T target) {
        // 步骤1:基础非空校验
        if (target == null) {
            return ValidationResult.fail("目标对象不能为空");
        }
        // 步骤2:具体校验(子类实现)
        ValidationResult specificResult = doValidate(target);
        if (specificResult.isFail()) {
            return specificResult;
        }
        // 步骤3:后置处理(可选)
        postValidate(target);
        return ValidationResult.success();
    }
    protected abstract ValidationResult doValidate(T target);
    protected void postValidate(T target) {
        // 默认空实现,子类可选覆盖
    }
}
// 2. 具体实现类
public class UserValidator extends AbstractValidator<User> {
    @Override
    protected ValidationResult doValidate(User user) {
        if (user.getName() == null || user.getName().length() < 2) {
            return ValidationResult.fail("用户名至少2个字符");
        }
        return ValidationResult.success();
    }
}
// 使用
UserValidator validator = new UserValidator();
ValidationResult result = validator.validate(user);

复用方式:所有校验器继承AbstractValidator,自动获得非空校验等通用逻辑。


企业级最佳实践:组合使用

实际项目中通常将上述模式组合:

校验架构分层:
├── 表现层(Controller)
│   ├── @Valid / @Validated 注解(处理基础字段校验)
│   └── 自定义注解(@Phone、@Email等)
├── 业务层(Service)
│   ├── 策略模式校验器(处理复杂业务规则)
│   └── 责任链校验器(处理流程化校验)
└── 基础设施层(Infrastructure)
    ├── 校验结果封装(ValidationResult)
    ├── 校验异常统一处理
    └── 校验规则配置中心(规则可配置化)

关键复用技巧

  1. 将校验逻辑剥离到独立模块(如validation-common),所有微服务依赖
  2. 使用SPI或Spring Factories实现校验器的自动发现
  3. 规则配置化:将校验规则放入数据库或配置中心,运行时动态加载

选择哪种复用方式取决于你的业务复杂度:简单校验用注解,复杂校验用策略模式,流程校验用责任链,固定骨架用模板方法。

抱歉,评论功能暂时关闭!