如何用密封类减少Kotlin表单验证中的if条件?
表单验证UseCase的优化方案
核心优化方向
1. 封装验证规则,消除重复if判断
把每个字段的验证条件、错误类型、提示信息封装成独立的规则单元,彻底告别零散的if分支。
2. 单一职责拆分
将验证逻辑从UseCase中抽离,让UseCase专注于业务流程,验证逻辑交给专门的验证器类维护。
3. 补充有意义的错误提示
原代码错误信息为空,优化后给用户明确的提示,提升交互体验。
具体实现代码
第一步:定义验证规则数据类
data class ValidationRule( val validate: () -> Boolean, val error: FormValidationError )
第二步:创建专门的表单验证器
class UserInfoValidator { fun validate(userInfo: UserInfo): FormValidationError? { val rules = listOf( // 姓名长度验证 ValidationRule( validate = { userInfo.name.length < 3 }, error = FormValidationError.NameFieldError("姓名长度不能少于3个字符") ), ValidationRule( validate = { userInfo.name.length > 10 }, error = FormValidationError.NameFieldError("姓名长度不能超过10个字符") ), // 姓氏长度验证 ValidationRule( validate = { userInfo.surname.length < 2 }, error = FormValidationError.LastNameError("姓氏长度不能少于2个字符") ), ValidationRule( validate = { userInfo.surname.length > 10 }, error = FormValidationError.LastNameError("姓氏长度不能超过10个字符") ) ) // 找到第一个不符合的规则并返回错误 return rules.firstOrNull { it.validate() }?.error } }
第三步:优化后的UseCase
// 可通过依赖注入方式传入验证器 private val validator: UserInfoValidator = UserInfoValidator() suspend operator fun invoke(userInfo: UserInfo): Resource<Unit> { validator.validate(userInfo)?.let { error -> return Resource.Error(type = error) } return currentUserRepository.insertCurrentUserInfo(userInfo) }
可选扩展:支持多错误收集
如果需要一次性返回所有验证错误,可以修改验证器返回错误列表:
fun validateAll(userInfo: UserInfo): List<FormValidationError> { return rules.filter { it.validate() }.map { it.error } }
然后在UseCase中判断处理:
val errors = validator.validateAll(userInfo) if (errors.isNotEmpty()) { // 可根据需求返回第一个错误或封装所有错误返回 return Resource.Error(type = errors.first()) }
额外优化建议
- 把验证的长度阈值(如3、10)抽成常量,便于统一维护修改
- 后续新增字段验证时,只需在验证器中添加新的
ValidationRule,无需改动UseCase逻辑 - 若需支持多语言,可将错误提示信息替换为字符串资源引用
内容的提问来源于stack exchange,提问作者Tunahan
相关产品推荐
相关产品推荐

