用Predicate组合设计模式重构校验逻辑,核心是将校验规则变为可组合、可复用、可读性强的一等公民;每个Predicate专注单一原子校验,通过and/or/negate声明式组合,配合封装的Validator统一处理错误与上下文。

用 Predicate 组合设计模式重构校验逻辑,核心不是堆砌条件,而是把“校验规则”变成可组合、可复用、可读性强的一等公民。它天然适配函数式思维,不依赖复杂框架,几行代码就能替代几十行 if-else 嵌套,且支持运行时动态拼装。
明确 Predicate 的职责边界
Predicate 是一个只返回 boolean 的函数接口,代表“某数据是否满足某个条件”。它本身不抛异常、不修改状态、不触发副作用——所有校验失败的提示、日志、错误码,都应由外层统一处理。这样保证每个 Predicate 纯净、专注、可测试。
- 一个 Predicate 对应一个原子校验点:比如 非空、邮箱格式、手机号长度为11
- 避免写成“用户名非空且长度在2~20之间且不能含特殊字符”,应拆为三个独立 Predicate
- 每个 Predicate 命名体现语义:
isNotBlank()、isValidEmail()、hasExactLength(11)
用 and/or/negate 实现声明式组合
JDK 自带的 Predicate.and()、Predicate.or()、Predicate.negate() 就是天然的组合子。它们返回新 Predicate,不改变原对象,支持链式调用,语义清晰。
- 用户注册校验可写成:
isNotBlank().and(hasMinLength(2)).and(hasMaxLength(20)) - 登录校验可写成:
isNotBlank().and(isValidEmail()).or(isValidPhone()) - 禁用账号判断:
isActive().negate()
封装通用校验器,屏蔽底层细节
直接裸用 Predicate 链易出错(如 null 安全、类型转换)。建议封装一层轻量校验器,统一处理上下文、错误收集和短路逻辑。
- 定义
Validator<T>接口,含test(T value)和explain()方法 - 提供工厂方法:
Validators.notBlank()、Validators.range(1, 100) - 支持批量校验并聚合错误:
validator.validateAll(List<User> users)返回 List<Error>
与责任链或规则引擎协同扩展
单一 Predicate 链适合字段级校验;当涉及跨字段、业务规则、状态流转时,可将 Predicate 作为责任链中 Handler 的核心判断逻辑,或作为规则引擎中的条件表达式单元。
- 例如订单创建前,先走
hasStock().and(isInServiceTime()).and(hasValidPaymentMethod())链 - 再交由后续 Handler 处理库存预占、风控拦截等动作
- 规则引擎 DSL 可解析成 Predicate 实例,实现“配置即校验”

















