Lambda校验核心是将Predicate作为一等公民封装规则,支持and/or链式组合、HashMap动态调度、ValidatingPredicate增强失败诊断,并统一返回结构化结果DTO解耦执行与消费。

用Lambda表达式实现变量校验,核心是把“校验行为”变成可传递、可组合、可复用的一等公民,而不是散落在各处的if-else。关键不在写得炫酷,而在结构清晰、职责分明、易于扩展。
把校验逻辑封装成Predicate函数
Java中Predicate<T>是最贴切的校验接口:输入一个对象,返回true/false。它天然支持and/or/negate链式组合,也便于统一收口处理失败反馈。
- 每个具体规则独立成Predicate,比如
Predicate<Order> isPaid = order -> Objects.nonNull(order.getPayTime()); - 多个规则组合:
isPaid.and(hasItems).and(notExpired),一行代码表达复合条件 - 避免在业务方法里硬编码判断,而是传入Predicate实例,让调用方决定用哪组规则
用HashMap集中管理校验器,按Key动态调度
不同场景(如创建订单、修改地址、发起退款)需要不同校验组合。用Map
- 定义常量key:
public static final String ORDER_CREATE_CHECK = "order_create"; - 启动时注入所有校验器:
checkMap.put(ORDER_CREATE_CHECK, isPaid.and(hasItems)); - 运行时根据业务类型取用:
checkMap.get("order_create").test(order) - 新增一种校验?只需加一个Predicate Bean,无需改原有调用逻辑
增强Predicate:失败时自动记录上下文与错误信息
原始Predicate只返回布尔值,但业务出错时需要知道“为什么失败”。可以包装一层装饰器,让Predicate在test()为false时触发日志或填充错误码。
- 自定义
ValidatingPredicate<T>,内部持有一个Predicate和一个Consumer<String>用于记录失败原因 - 调用
testWithReason(obj),返回Result<Boolean, String>或直接填充DTO中的failedMessages字段 - 例如:
new ValidatingPredicate(isPaid, msg -> result.addFailure("未支付")) - 这样既保持函数式风格,又不丢失诊断能力
校验结果统一建模,解耦执行与消费
不要让校验逻辑直接抛异常或写日志——那会绑架调用方。推荐返回结构化结果对象,比如UserCheckResultDTO,含isValid、failedMessages等字段。
- 所有校验器最终都汇聚到这个DTO上,上层根据isValid决定流程走向
- 前端可直取failedMessages展示;后台可按failedMessages分类统计高频失败原因
- 后续加风控拦截、灰度开关、异步审计,都基于这个结果模型扩展,不侵入校验本身

















