Uber Go 语言编程规范:功能选项

函数选项是一种模式,在这种模式中,您声明一个不透明的 Option 类型,该类型在某些内部结构中记录信息。您接受这些选项的可变数量,并根据内部结构上的选项记录的完整信息进行操作。

在构造函数和其他您认为需要扩展的公共api中,使用此模式的可选参数,特别是当您已经在这些函数上有三个或更多的参数时。

Bad

// package db

func Open(
  addr string,
  cache bool,
  logger *zap.Logger
) (*Connection, error) {
  // ...
}


//cache和logger 参数必须始终提供,即使用户希望使用默认值

db.Open(addr, db.DefaultCache, zap.NewNop())
db.Open(addr, db.DefaultCache, log)
db.Open(addr, false /* cache */, zap.NewNop())
db.Open(addr, false /* cache */, log)

Good

// package db
//定义一个选项接口
type Option interface {
  // ...
}

//返回Cache选项
func WithCache(c bool) Option {
  // ...
}

//返回Logger选项
func WithLogger(log *zap.Logger) Option {
  // ...
}

// Open creates a connection.
func Open(
  addr string,
  opts ...Option, //使用选项参数,可变参数
) (*Connection, error) {
  // ...
}

//只有在需要时才提供选项

db.Open(addr)
db.Open(addr, db.WithLogger(log))
db.Open(addr, db.WithCache(false))
db.Open(
  addr,
  db.WithCache(false),
  db.WithLogger(log),
)

我们建议的实现此模式的方法是:使用一个Option 接口,并且该接口持有一个未导出的方法,在一个未导出的options 结构体上记录相关选项:

//在未导出的 结构体 options 上记录相关选项
type options struct {
  cache  bool
  logger *zap.Logger
}

//提供一个Option接口
type Option interface {
  //提供一个未导出的方法操作相关选项
  apply(*options)
}

type cacheOption bool

func (c cacheOption) apply(opts *options) {
  opts.cache = bool(c)
}

func WithCache(c bool) Option {
  return cacheOption(c)
}

type loggerOption struct {
  Log *zap.Logger
}

func (l loggerOption) apply(opts *options) {
  opts.logger = l.Log
}

func WithLogger(log *zap.Logger) Option {
  return loggerOption{Log: log}
}

// Open creates a connection.
func Open(
  addr string,
  opts ...Option,
) (*Connection, error) {
  options := options{
    cache:  defaultCache,
    logger: zap.NewNop(),
  }

  for _, o := range opts {
    o.apply(&options)
  }

  // ...
}

注意,有一种方法可以用闭包实现这个模式,但是我们相信上面的模式为作者提供了更多的灵活性,并且更容易为用户调试和测试。它允许在测试和模拟中相互比较选项,而在闭包中则不可能这样做。而且,它允许选项options 实现其他接口,包括fmt.Stringer

允许用户以可读的字符串形式来表示选项options。

另外,请参阅:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DreamCatcher

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值