大家好,我是小白,有點黑的那個白。
“專業(yè)、務實、高效、創(chuàng)新、把客戶的事當成自己的事”是我們每一個人一直以來堅持追求的企業(yè)文化。 創(chuàng)新互聯(lián)公司是您可以信賴的網(wǎng)站建設服務商、專業(yè)的互聯(lián)網(wǎng)服務提供商! 專注于網(wǎng)站設計、成都網(wǎng)站設計、軟件開發(fā)、設計服務業(yè)務。我們始終堅持以客戶需求為導向,結合用戶體驗與視覺傳達,提供有針對性的項目解決方案,提供專業(yè)性的建議,創(chuàng)新互聯(lián)建站將不斷地超越自我,追逐市場,引領市場!
最近遇到一個問題,因為業(yè)務需求,需要對接三方平臺.
而三方平臺提供的一些HTTP(S)接口都有統(tǒng)一的密鑰生成規(guī)則要求.
為此我們封裝了一個獨立的包 xxx-go-sdk 以便維護和對接使用.
其中核心的部分是自定義HTTP Client,如下:
type Client struct {}
func (c *Client) do() {
// 實現(xiàn)統(tǒng)一的加密和簽名邏輯
// 統(tǒng)一調(diào)用net/http
}
// 訂單列表接口
func (c *Client) OrderList(){
c.do()
}
// 訂單發(fā)貨接口
func (c *Client) OrderDelivery(){
c.do()
}
// ... 其他接口
一些平臺會要求appKey/appSecret等信息,所以Client結構體就變成了這樣,這時參數(shù)還比較少, 而且是必填的參數(shù),我們可以提供構造函數(shù)來明確指定。
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 參數(shù)來控制超時呢?
或許你會說這還不簡單,像下面一樣再加一個參數(shù)唄
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
}
那再加些其他的參數(shù)呢?那構造函數(shù)的參數(shù)是不是又長又串,而且每個參數(shù)不一定是必須的,有些參數(shù)我們有會考慮默認值的問題。
為此,勤勞但尚未致富的 gophers 們使用了總結一種實踐模式
首先提取所有需要的參數(shù)到一個獨立的結構體 Options,當然你也可以用 Configs 啥的.
type Options struct {
AppKey string
AppSecret string
}
然后為每個參數(shù)提供設置函數(shù)
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
}
}
這樣我們就為每個參數(shù)設置了獨立的設置函數(shù)。返回值 func(*Options)
看著有點不友好,我們提取下定義為單個 Option
調(diào)整一下代碼
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
}
}
當我們需要添加更多的參數(shù)時,只需要在 Options 添加新的參數(shù)并添加新參數(shù)的設置函數(shù)即可。
比如現(xiàn)在要添加新的參數(shù) Timeout
type Options struct {
AppKey string
AppSecret string
Timeout. time.Duration // 新增參數(shù)
}
// Timeout 的設置函數(shù)
func WithTimeout(timeout time.Duration) Option {
return func(o *Options) {
o.Timeout = timeout
}
}
這樣后續(xù)不管新增多少參數(shù),只需要新增配置項并添加獨立的設置函數(shù)即可輕松擴展,并且不會影響原有函數(shù)的參數(shù)順序和個數(shù)位置等。
至此,每個選項是區(qū)分開來了,那么怎么作用到我們的 Client 結構體上呢?
首先,配置選項都被提取到了 Options 結構體中,所以我們需要調(diào)整一下 Client 結構體的參數(shù)
type Client struct {
options *Options
}
其次,每一個選項函數(shù)返回 Option,那么任意多個就是 ...Option,我們調(diào)整一下構造函數(shù) NewClient 的參數(shù)形式,改為可變參數(shù),不在局限于固定順序的幾個參數(shù)。
func NewClient(options ...Option) *Client {
c := new(Client)
c.Options = ?
return c
}
然后循環(huán)遍歷每個選項函數(shù),來生成Client結構體的完整配置選項。
func NewClient(options ...Option) *Client {
opts := new(Options)
for _, o := range options {
o(opts)
}
c := new(Client)
c.Options = opts
return c
}
那么怎么調(diào)用呢?對于調(diào)用方而已,直接在調(diào)用構造函數(shù)NewClient()的參數(shù)內(nèi)添加自己需要的設置函數(shù)(WithXXX)即可
client := NewClient(
WithAppKey("your-app-key"),
WithAppSecret("your-app-secret"),
)
當需要設置超時參數(shù),直接添加 WithTimeout即可,比如設置3秒的超時
client := NewClient(
WithAppKey("your-app-key"),
WithAppSecret("your-app-secret"),
WithTimeout(3*time.Second),
)
配置選項的位置可以任意設置,不需要受常規(guī)的固定參數(shù)順序約束。
可以看到,這種實踐模式主要作用于配置選項,利用函數(shù)支持的特性來實現(xiàn)的,為此得名 Functional Options Pattern,優(yōu)美的中國話叫做「函數(shù)選項模式」。
最后, 我們總結回顧一下在Go語言中函數(shù)選項模式的優(yōu)缺點
這是特性,不是缺點 - -!
當前名稱:Go語言實踐模式
URL地址:http://chinadenli.net/article16/dsoisdg.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供響應式網(wǎng)站、微信小程序、虛擬主機、網(wǎng)站內(nèi)鏈、網(wǎng)站維護、建站公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)