函数式模型(Functional Options Pattern)是go中常用的一种模型

比如使用的ElasticSearch ,我们可以使用这样的方式调用search api

body := `
    {
        "query": {
            "term": {
                "_id": "sss"
            }
        },
        "pit": {
            "id":  "iddd", 
            "keep_alive": "3m"  
        }
    }
`
es, _ := elasticsearch.NewDefaultClient()
json.NewDecoder(&query_buffer).Decode(&body)
res, err := es.Search(
    es.Search.WithAllowPartialSearchResults(true),
    es.Search.WithBody(&query_buffer),
	)

查看源码可以发现这个Search函数就是使用的函数式模型:

type Search func(o ...func(*SearchRequest)) (*Response, error)

// SearchRequest configures the Search API request.
//
type SearchRequest struct {
	Index        []string
	DocumentType []string
	Body         io.Reader

	AllowNoIndices             *bool
	AllowPartialSearchResults  *bool
	Analyzer                   string
	AnalyzeWildcard            *bool
	BatchedReduceSize          *int
	CcsMinimizeRoundtrips      *bool
	DefaultOperator            string
	Df                         string
    ......

	ctx context.Context
}
.....
func (f Search) WithContext(v context.Context) func(*SearchRequest) {
	return func(r *SearchRequest) {
		r.ctx = v
	}
}

// WithIndex - a list of index names to search; use _all to perform the operation on all indices.
//
func (f Search) WithIndex(v ...string) func(*SearchRequest) {
	return func(r *SearchRequest) {
		r.Index = v
	}
}

// WithDocumentType - a list of document types to search; leave empty to perform the operation on all types.
//
func (f Search) WithDocumentType(v ...string) func(*SearchRequest) {
	return func(r *SearchRequest) {
		r.DocumentType = v
	}
}

函数式模型原理

函数式模型一般是:

定义设置options对象sturct结构,这里是DBOptions

type DBOptions struct {

    host     string

    port     int

    user     string

    password string

    dbname   string

    charset  string

}

定义一个函数类型type,接受参数是DBOptions指针

type Option func(options *DBOptions)

定义设置DBOptions 每一项的具体配置的赋值函数WithXXX,名字没有固定自己定义即可,返回的是一个 Option 函数。

每个WithXXX函数中return之后的匿名函数实现具体配置的赋值逻辑。

func WithHost(host string) Option {

    return func(options *DBOptions) {

        options.host = host

    }

}

func WithPort(port int) Option {

    return func(options *DBOptions) {

        options.port = port

    }

}

func WithUser(user string) Option {

    return func(options *DBOptions) {

        options.user = user

    }

}

func WithPassword(password string) Option {

    return func(options *DBOptions) {

        options.password = password

    }

}

func WithDBName(dbname string) Option {

    return func(options *DBOptions) {

        options.dbname = dbname

    }

}

func WithCharset(charset string) Option {

    return func(options *DBOptions) {

        options.charset = charset

    }

}

定义 一个函数NewOpts,参数是一串Option函数,在该函数中依次调用每个Option函数去处理每个配置项的赋值逻辑。最后返回配置好的DBOptions。

在调用Option函数之前,可以有默认的配置项。若是不传入任何Option函数,则使用默认配置值

func NewOpts(opts ...Option) DBOptions {

    dbopts := &DBOptions{

        host:     "127.0.0.1",

        port:     3306,

        user:     "root",

        password: "123456",

        dbname:   "test",

        charset:  "utf8",

    }

    for _, opt := range opts {

        opt(dbopts)

    }

    return *dbopts

}

调用方式:

opts := NewOpts(

      WithHost("188.167.23.12"),

     //func(options *DBOptions) { options.port = port } Option函数  

    WithDBName("pro"),

     WithCharset("utf8"),

    )

    fmt.Println(opts)

需要设置什么配置项,就可以调用相关的With函数去设置,不设置就使用默认值。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部