Go语言实践模式函数选项模式(FunctionalOptionsPattern)
什么是函数选项模式
大家好,我是小白,有点黑的那个白。
最近遇到一个问题,因为业务需求,需要对接第三方平台.
而三方平台提供的一些HTTP(S)接口都有统一的密钥生成规则要求.
为此我们封装了一个独立的包 xxx-go-sdk 以便维护和对接使用.
其中核心的部分是自定义HTTP Client,如下: type Client struct {} func (c *Client) do() { // 实现统一的加密和签名逻辑 // 统一调用net/http } // 订单列表接口 func (c *Client) OrderList(){ c.do() } // 订单发货接口 func (c *Client) OrderDelivery(){ c.do() } // ... 其他接口
一些平台会要求appKey/appSecret等信息,所以Client结构体就变成了这样,这时参数还比较少, 而且是必填的参数,我们可以提供构造函数来明确指定。 type Client struct { AppKey string AppSecret string } func NewClient(appKey string, appSecret string) *Client { c := new(Client) c.AppKey = appKey c.AppSecret = appSecret return c }
看起来很满足,但是当我们需要增加一个 Timeout 参数来控制超时呢?
或许你会说这还不简单,像下面一样再加一个参数呗 type Client struct { AppKey string AppSecret string Timeout time.Duration } func NewClient(appKey string, appSecret string, timeout time.Duration) *Client { c := new(Client) c.AppKey = appKey c.AppSecret = appSecret c.Timeout = timeout return c }
那再加些其他的参数呢?那构造函数的参数是不是又长又串,而且每个参数不一定是必须的,有些参数我们又会考虑默认值的问题。
为此,勤劳但尚未致富的 gophers 们使用了总结一种实践模式
首先提取所有需要的参数到一个独立的结构体 Options,当然你也可以用 Configs 啥的. type Options struct { AppKey string AppSecret string }
然后为每个参数提供设置函数 func WithAppKey(appKey string) func(*Options) { return func(o *Options) { o.AppKey = appKey } } func WithAppSecret(appSecret string) func(*Options) { return func(o *Options) { o.AppSecret = appSecret } }
这样我们就为每个参数设置了独立的设置函数。返回值 func(*Options) 看着有点不友好,我们提取下定义为单个 Option 调整一下代码type Option func(*Options) func WithAppKey(appKey string) Option { return func(o *Options) { o.AppKey = appKey } } func WithAppSecret(appSecret string) Option { return func(o *Options) { o.AppSecret = appSecret } }
当我们需要添加更多的参数时,只需要在 Options 添加新的参数并添加新参数的设置函数即可。
比如现在要添加新的参数 Timeout type Options struct { AppKey string AppSecret string Timeout. time.Duration // 新增参数 } // Timeout 的设置函数 func WithTimeout(timeout time.Duration) Option { return func(o *Options) { o.Timeout = timeout } }
这样后续不管新增多少参数,只需要新增配置项并添加独立的设置函数即可轻松扩展,并且不会影响原有函数的参数顺序和个数位置等。
至此,每个选项是区分开来了,那么怎么作用到我们的 Client 结构体上呢?
首先,配置选项都被提取到了 Options 结构体重,所以我们需要调整一下 Client 结构体的参数 type Client struct { options *Options }
其次,每一个选项函数返回 Option,那么任意多个就是 ...Option,我们调整一下构造函数 NewClient 的参数形式,改为可变参数,不再局限于固定顺序的几个参数。 func NewClient(options ...Option) *Client { c := new(Client) c.Options = ? return c }
然后循环遍历每个选项函数,来生成Client结构体的完整配置选项。 func NewClient(options ...Option) *Client { opts := new(Options) for _, o := range options { o(opts) } c := new(Client) c.Options = opts return c }
那么怎么调用呢?对于调用方而已,直接在调用构造函数NewClient()的参数内添加自己需要的设置函数(WithXXX)即可 client := NewClient( WithAppKey("your-app-key"), WithAppSecret("your-app-secret"), )
当需要设置超时参数,直接添加 WithTimeout即可,比如设置3秒的超时 client := NewClient( WithAppKey("your-app-key"), WithAppSecret("your-app-secret"), WithTimeout(3*time.Second), )
配置选项的位置可以任意设置,不需要受常规的固定参数顺序约束。
可以看到,这种实践模式主要作用于配置选项,利用函数支持的特性来实现的,为此得名 Functional Options Pattern,优美的中国话叫做「函数选项模式」。 总结
最后, 我们总结回顾一下在Go语言中函数选项模式的优缺点 优点支持多参数; 支持参数任意位置顺序; 支持默认值设置; 向后兼容,扩展性极佳; 用户使用行为一致, 体感良好. 缺点
这是特性,不是缺点 - -! 增加了Options结构和Option定义; 针对每个参数都有对应的设置函数,每个选项函数的实现代码量好像多了一些;
网络空间主权资源及网络安全的目的网络空间是人类创造的新的生产与生活空间,是继陆海空天之后的第五空间。在这个新的人类空间里每个国家占有多大范围?有什么特殊资源?这是涉及网络主权和网络资源的所有权归属的大是大非问题。
歌尔股份公司已经积累了AR核心器件模组以及AR整机项目的相关项目经验36氪获悉,歌尔股份在互动平台表示,公司看好VRAR行业的未来发展,并在相关领域内进行了相应的人才技术和产品布局。公司可以为客户提供AR光学器件及模组AR光机等核心零组件以及AR整
一个没有正式工作的女性,却有三百多个微信好友,这种情况正常吗?自从堂哥出去打工以后,堂嫂已经连续多年没有工作了,在家也不照顾孩子,还经常和不同的男人来往,婶子让堂哥离婚,直到去年,我发现了堂嫂的一个秘密后,我对婶子说,如果堂哥真的和堂嫂离婚了
奶奶看电视声音开很大声都听不清楚,戴上助听器能听见电视的声音吗?你好,估计是你奶奶的听力出现了问题,一般戴上助听器经过康复后是可以听清楚电视的声音,建议带上奶奶去当地的听力机构咨询检查听力。助听器可以帮助老人听到声音,戴上助听器的效果也同自己的
腾讯优酷和爱奇艺相比,哪个视频软件好?极客谈科技局,全新视角全新思路,伴你遨游神奇的科技世界。在我们平时的生活中,腾讯优酷爱奇艺,是我们平时追剧的三大神器,看电视剧网剧电影综艺等节目,基本都要用到这几个视频播放软件,记
TWS市场进入洗牌期,电源管理技术日趋成熟电子发烧友网报道(文黄山明)就在不久前,苹果刚举办完新品发布会,值得注意的是,此次苹果发布了新款的AirPods3,也是自AirPods系列发布以来的第五个年头,或者说是TWS耳机
曹晓烨刘东现货互联网交易犯罪的刑事责任研究曹晓烨上海市杨浦区人民检察院副检察长刘东上海市杨浦区人民检察院第六检察部检察官助理。内容摘要现货互联网交易犯罪涉案人员众多涉案金额巨大,严重侵害投资者的财产权益,强烈冲击着我国现货
杭州是不是只用支付宝结账?可以很明确的说杭州不拒绝微信付款,作为移动支付之城,微信和支付宝都是可以用的支付方式。商家收款如果只支持支付宝,这等于是抛弃部分用微信支付的用户,商家可不会这么傻。不少用户在杭州完
VR技术现在发展到什么地步了?前段时间热映的电影头号玩家,一度引起了人们的热议。除了精彩的故事情节之外,电影中游戏玩家们超级炫酷的VR虚拟世界的游戏体验,引起了大家的热议。人们不禁想问近几年来就一直频繁地听到V
你看好腾讯微视的未来吗?经过一年多的发展,抖音自2018年春节之后达到了高光时间,至今热度一直不减。此前,关于抖音狙击快手灭掉微博杀死朋友圈的报道不断。加上微信QQ用户同比增幅的下滑,以及抖音用户的暴增和
如何看待iPhoneX取消运营商文字显示这件事?据说,新出炉的iPhoneX在刚刚出世就面对很多争议,不仅是头顶上有个刘海,更严重的是,苹果新版的手机取消了电信运营商名称的显示。多家外媒报道,在以往的iPhone或者其他安卓手机