之前在写一个限流器的时候,习惯性的用了选项模式来配置 type LeakyLimiter struct { lock sync.Mutex last time.Time sleep time.Duration perReq time.Duration maxSlack time.Duration } type leakyOptions struct { maxSlack time.Duration } type LeakyOption interface { apply(*leakyOptions) } type leakyOptionFunc func(options *leakyOptions) func (l leakyOptionFunc) apply(o *leakyOptions) { l(o) } func WithMaxSlack(maxSlack time.Duration) LeakyOption { return leakyOptionFunc(func(options *leakyOptions) { options.maxSlack = maxSlack }) } func NewLeakyLimiter(rate int, opts ...LeakyOption) *LeakyLimiter { options := leakyOptions{ maxSlack: -10 * time.Second / time.Duration(rate), } for _, option := range opts { option.apply(&options) } return &LeakyLimiter{ perReq: time.Second / time.Duration(rate), maxSlack: options.maxSlack, } } 但是突然想到,能不能直接暴露出能够修改可配置项的函数 type LeakyLimiter struct { lock sync.Mutex last time.Time sleep time.Duration perReq time.Duration maxSlack time.Duration } func (l *LeakyLimiter) WithMaxSlack(maxSlack time.Duration) *LeakyLimiter { l.maxSlack = maxSlack return l } func NewLeakyLimiter(rate int) *LeakyLimiter { return &LeakyLimiter{ perReq: time.Second / time.Duration(rate), maxSlack: -10 * time.Second / time.Duration(rate), } } 相比于这种直接配置的方式,选项模式的优点在哪里呢?感觉扩展性和可读性也没有提升,这种方式也可以链式调用。 我个人想的可能是不暴露修改的接口,在调用构造函数以后就不会被修改了安全一点。 除了这一个以外还有其他的考量吗?希望听听各位大大的分析