Info

以下说明以 Golang 为例,但设计逻辑可以运用于所有支持闭包和函数参数的编程语言

一个常用的例子:

type option func(*Foo)
 
// Option sets the options specified.
func (f *Foo) Option(opts ...option) {
    for _, opt := range opts {
        opt(f)
    }
}
 
// Verbosity sets Foo's verbosity level to v.
func Verbosity(v int) option {
    return func(f *Foo) {
        f.verbosity = v
    }
}
 
foo.Option(pkg.Verbosity(3))

这个例子可以适用于大部分的情况,不过如果希望只是临时的调整某个设置,然后在调用之后恢复到之前的设置,可以考虑更进一步:

type option func(f *Foo) option
 
// Option sets the options specified.
// It returns an option to restore the last arg's previous value.
func (f *Foo) Option(opts ...option) (previous option) {
    for _, opt := range opts {
        previous = opt(f)
    }
    return previous
}
 
// Verbosity sets Foo's verbosity level to v.
func Verbosity(v int) option {
    return func(f *Foo) option {
        previous := f.verbosity
        f.verbosity = v
        return Verbosity(previous)
    }
}
 
func DoSomethingVerbosely(foo *Foo, verbosity int) {
    // Could combine the next two lines,
    // with some loss of readability.
    prev := foo.Option(pkg.Verbosity(verbosity))
    defer foo.Option(prev)
    // ... do some stuff with foo under high verbosity.
}

参考链接

  • Rob Pike’s Blog
  • 《Go 语言精进之路:从新手到高手的编程思想、方法和技巧1》,白明,25.4 实现功能选项模式。