You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

可返回对象全部校验失败原因的常用设计模式有哪些?

适用方案:通知(Notification)模式

该模式专门针对批量校验场景设计,核心逻辑是收集所有校验错误后统一返回,而非遇到第一个错误就中断执行,完全匹配你需要返回对象全部无效原因的需求,同时可以解决现有代码耦合度高、扩展性差的问题。

现有代码的核心问题

  • 校验逻辑耦合在类构造函数中,新增校验规则、新增参数都需要修改构造函数的init代码块,违反开闭原则
  • 用构造函数抛异常的方式处理预期内的参数校验问题,既增加了上层调用的try-catch负担,也不符合异常仅用于处理非预期错误的设计原则
  • 错误信息存储格式灵活度低,后续要扩展结构化错误(比如错误码、关联字段)的成本很高

优化实现步骤

1. 定义基础结构

// 自定义异常兼容原有逻辑
class InvalidFooException(message: String): Exception(message)

2. 重构Foo类,用私有构造+工厂方法创建实例

将校验逻辑从构造函数抽离到工厂方法,保证只有校验通过的合法实例才会被创建,同时校验规则可独立配置,扩展性更强:

class Foo private constructor(val a: String, val b: String) {
    companion object {
        // 校验规则可独立配置,新增规则仅需要往列表中添加元素即可
        private val validationRules = listOf<(String?, String?) -> String?>(
            { a, _ -> if (a == null) "a 不能为空" else null },
            { _, b -> if (b == null) "b 不能为空" else null }
        )

        fun create(a: String?, b: String?): Result<Foo> {
            val errors = validationRules.mapNotNull { rule -> rule(a, b) }
            return if (errors.isEmpty()) {
                Result.success(Foo(a, b))
            } else {
                Result.failure(InvalidFooException(errors.joinToString(";")))
            }
        }
    }
}

3. 上层调用逻辑优化

不需要依赖try-catch处理校验结果,代码可读性更高:

fun parentMethod(a: String?, b: String?) {
    // 原有业务逻辑
    Foo.create(a, b).fold(
        onSuccess = { foo ->
            // 处理合法的Foo实例
        },
        onFailure = { e ->
            LOG.info("创建Foo实例出错", e.message) // 此处可拿到全部错误信息
        }
    )
}

进阶优化方向

  • 校验规则泛化:如果多个业务类都需要类似校验,可以抽象通用的ValidationRule接口,不同业务类的校验规则分别实现接口,运行时动态组装规则,完全解耦校验逻辑和业务类
  • 错误结构化:把错误信息从纯字符串改成包含错误字段、错误码、错误描述的结构化对象,方便上游系统做针对性提示、国际化适配等处理
  • 复用框架能力:如果是Web接口的Payload校验场景,JSR-380(Bean Validation)规范以及Spring Validation等框架原生支持全量错误收集,无需自己手动实现规则逻辑

内容的提问来源于stack exchange,提问作者stk1234

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 18:36:05