Go 語言常見錯誤 - 不使用 function option 模式

在使用 Golang 進行復雜的開發任務時,處理一個結構體有許多可選的配置項是常有的事。這也是在許多函數設計中共有的特徵,因爲這使得函數更容易使用,靈活性更強。然而,有時我們可能會看到錯誤的實踐,那就是 “遺漏使用 Function Option 模式”。在這篇文章中,我將詳細解釋Function Option的概念,並指出爲什麼我們應該使用它。我還將給出實例來展示如果忽略了Function Option,可能會出現哪些問題。

Function Option 的基本概念

在 Go 語言中,Function Option是一種用於設計準備接受許多設置項的結構體的技術。在沒有 Function Option 的情況下,我們通常返回結構體的指針,並通過函數設置可選項。下面是一個無Function Option的示例:

type Config struct {
    A string
    B int
}

func NewConfig() *Config {
    return &Config {
        A: "default A",
        B: 0,
    }
}

func main() {
    cfg := NewConfig()
    cfg.A = "non-default A"
    cfg.B = 1
}

遺漏使用 Function Option 的問題

上述代碼的問題在於,如果 Config 結構體有許多設置項,我們就必須設置每一項,即使我們只關心某幾項。此外,散亂的設置代碼可能混入我們的業務代碼中,導致代碼變得難以閱讀和維護。

對於使用默認選項的情況,我們得到的是一個部分初始化的結構體,我們可能忘記設置重要的選項,引入 bug。另一個問題是,如果添加新的設置項,我們需要在代碼中找到每個實例並更新它們,這會很麻煩。

應用 Function Option 模式

如果我們使用函數選項模式,上述代碼將被優化爲:

type Config struct {
    A string
    B int
}

type Option func (*Config)

func WithA(a string) Option {
    return func(c *Config) {
        c.A = a
    }
}

func WithB(b int) Option {
    return func(c *Config) {
        c.B = b
    }
}

func NewConfig(opts ...Option) *Config {
    config := &Config{
        A: "default A",
        B: 0,
    }
    for _, opt := range opts {
        opt(config)
    }
    return config
}

func main() {
    cfg := NewConfig(
        WithA("non-default A"),
        WithB(1),
    )
}

這裏,WithA()WithB()函數返回的是改變Config的函數,而NewConfig()接受這些函數作爲參數。這樣做帶來了以下優點:

結語

忽略 Function Option 模式可能會導致代碼混亂,增加代碼維護的難度,並可能引入錯誤。在設計接受許多設置項的函數或類型時,使用 Function Option 模式是一種非常好的做法。我希望本文可以幫助大家更好地理解和使用這種模式,並寫出更優雅、可讀性更強的 Go 代碼。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/jdRMRfwGT3av9r8CjeLwXA