go的with模式2
这种方式称为链式调用。用来构建对象。
1.示例代码
本文的目的是学习如何填充Fields字段。
package main
import (
"fmt"
)
type Schema struct {
CollectionName string
Fields []*Field
}
func NewSchema() *Schema {
return &Schema{}
}
func (s *Schema) WithField(f *Field) *Schema {
s.Fields = append(s.Fields, f)
return s
}
type Field struct {
Name string
Description string
}
func NewField() *Field {
return &Field{}
}
func (s *Schema) WithName(name string) *Schema {
s.CollectionName = name
return s
}
func (f *Field) WithName(name string) *Field {
f.Name = name
return f
}
func (f *Field) WithDescription(desc string) *Field {
f.Description = desc
return f
}
func main() {
schema := NewSchema().WithName("hello").
WithField(NewField().WithName("tom").WithDescription("this is a desc1")).
WithField(NewField().WithName("kate").WithDescription("this is a desc2")).
WithField(NewField().WithName("sam").WithDescription("this is a desc3"))
fmt.Println(schema.CollectionName)
}
这段代码连续使用了几个WithField()函数,对Schema.Fields切片进行构建。
这种方式一般适用于初始化,比如建表。
如果是你对Fields字段进行赋值,你会怎么做?我想大概的常规思路就先新建Field对象,然后append,就例如如下代码:
f1 := &Field{}
f2 := &Field{}
f3 := &Field{}
schema.Fields = append(schema.Fields,f1)
schema.Fields = append(schema.Fields,f2)
schema.Fields = append(schema.Fields,f3)
在这里总结一下:
- 对结构体的切片可以连续使用WithField()函数。
- 如果是对结构体其它非切片字段可以使用withXXX()函数。
2.链式调用的优点
下面总结了一些WithField链式调用的几个优点:
1.封装性:
WithField()
方法封装了向Fields
切片添加字段的逻辑。这意味着如果将来需要修改添加字段的方式(例如,添加一些验证逻辑或格式化逻辑),你只需修改WithField()
方法即可,而不需要修改所有使用append()
的地方。这有助于减少代码的重复,并提高代码的可维护性。
2.表达性:
链式调用不仅使代码更简洁,而且更具表达性。它清晰地表达了你的意图:你正在构建一个Schema
对象,并逐个添加字段。相比之下,直接使用append()
可能会让代码的意图不那么明显,特别是当append()
调用散布在代码的不同部分时。
3.支持复杂逻辑:
如果添加字段的过程需要执行一些复杂的逻辑(如验证、转换或基于其他字段的决策),那么将这些逻辑封装在WithField()
方法中会更加方便和高效。相比之下,直接在append()
调用前后添加这些逻辑会使代码更加杂乱无章。