Go使用选项模式的优点是什么?-灵析社区

无敌铃铃后

之前在写一个限流器的时候,习惯性的用了选项模式来配置 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), } } 相比于这种直接配置的方式,选项模式的优点在哪里呢?感觉扩展性和可读性也没有提升,这种方式也可以链式调用。 我个人想的可能是不暴露修改的接口,在调用构造函数以后就不会被修改了安全一点。 除了这一个以外还有其他的考量吗?希望听听各位大大的分析

阅读量:18

点赞量:0

问AI
个人经验来参考: * 因为 Go 的常驻内存,一种是初始化启动、还一种是按需启动。 * 常驻内存下,多个依赖的服务,其实希望的是 "*LeakyLimiter" 是一致的,如果改成对象调整,当 A、B 两个依赖这个服务的指针会因为内部变化而影响另外一个。 *** 关于第二点的补充: 比如,"c2" 和 "c1" 因为调用的是同一个 "l",因为 "l.WithCount(3)" 导致 "l" 会互相影响 package main import "fmt" func main() { l := NewLimiter(5) c1 := NewCase(l) c2 := NewCase(l.WithCount(3)) fmt.Println(c1, c2) } type Case struct { limiter *Limiter } func NewCase(limiter *Limiter) *Case { return &Case{ limiter: limiter, } } func (c *Case) Allow() bool { return c.limiter.Allow() } type Limiter struct { Count int } func NewLimiter(count int) *Limiter { return &Limiter{ Count: count, } } func (l *Limiter) WithCount(c int) *Limiter { l.Count = c return l } func (l *Limiter) Allow() bool { return l.Count > 0 }