validator阅读

应领导要求把go-validator引入到团队的基础库中,作为可重用代码。同事也看了beego中validator的实现。

下面针对beego和go-validator的设计做下对比:

// Error show the error
type Error struct {
	Message, Key, Name, Field, Tmpl string
	Value                           interface{}
	LimitValue                      interface{}
}

beego 中自定义Error和Result,而不是使用内置error类型,这个设计显得多余。

type TextErr struct {
	Err error
}

而go-validator,采用golang类库设计中常见的装饰者模式,上层可以作为error处理,也可以断言为具体go-validator的错误类型,做进一步处理。

go-valicator 因为支持一个字段多种验证,所以引入type ErrorArray []error,因为字段验证逻辑的时间复杂度是常数,如果担心这里是性能瓶颈,可以简单做一个benchmark结果是比beego要好一些。

beego还使用了面向对象设计中常用的模板方法模式,将各验证func抽象成接口统一操作,这里可能是设计过度

// Validator interface
type Validator interface {
	IsSatisfied(interface{}) bool
	DefaultMessage() string
	GetKey() string
	GetLimitValue() interface{}
}

接口中定义了GetKey和GetLimitValue,这种方法比较鸡肋,用户可能不需要这种信息,因为这是用户传入的。

go-validator的可测试性也比较强,beego的测试有点类似于黑盒测试case可读性不强且错误因为没有明确的类型导致接入方不好做容错。

下面说下validator一些设计点:

  • 允许调用方注册自定义的验证方法。
  • 提供defaultValidator对象,调用方直接使用pkg名调用exported方法即可,不需要维护validator对象。这种设计比较常见,只有当该类库中启动对象的参数会导致类库功能变化比较多,且可以根据多种场景调整时,调用方才需要自己维护该对象。
  • 把调用方需要验证的变量分为两个层级,structnonstuctstruct可能存在嵌套,Validate方法提供了递归的验证方法;nonstruct可以使用Valid方法,当然这里你也可以传入struct但是,这里没有递归直接将变量传递给buildins.go中的方法进行验证。

后续应领导要求,引入了filter功能:对传入的变量先filter,然后利用filter的结果做验证,并且需要把filter的结果反馈给上层。

这里主要是把实现了FilterAndValidateFilterAndValid

FilterAndValid方法保持了Valid直接值传递,会返回filter的结果。

FilterAndValidate方法只接受指针,直接修改原始数据即可,没有采用复制的方式,也是因为reflect过程中如果想要修改参数的内容,就需要传入的是指针。

(本文完)

validator阅读
Share this