淺談 Go 語言 Optional 模式和 Builder 模式

在 Go 語言中,Optional 模式和 Builder 模式都是用於對象構建和配置的重要設計模式,但它們各自具有獨特的特點和應用場景。但是使用起來也是非常的類似,就好比電動車和摩托車,都能讓你不費太多力氣的騎行,把你送到目的地,這篇文章我們就來討論一下這兩個模式的本質區別和不同的使用場景。

我們首先聲明一個結構體,後面我們就研究使用兩種不同方式來創建這個結構體的實例:

type Person struct {
 name    string
 age     int
 address string
}

Optional 模式

Optional 模式,也稱爲選項模式或函數選項模式,是一種用於在函數或結構體構造中提供靈活配置選項的設計模式。它允許以清晰、可讀的方式爲函數或結構體傳遞一系列的選項,而不是強制使用大量的參數或固定的配置。

實現方式

在 Go 語言中,Optional 模式通常通過函數選項(functional options)來實現。每個選項函數都可以根據需要修改結構體的字段或者配置。這種方法常用於構造函數,允許根據需求定製對象的屬性。

先聲明一個 functional options:

type Option func(*Person)

然後在 New 函數中允許專遞多個 Option:

func NewPerson(opts ...Option) *Person {
 p := &Person{}
 for _, opt := range opts {
  opt(p)
 }
 return p
}

然後實現 Option:

func WithName(name string) Option {
 return func(person *Person) {
  person.name = name
 }
}

func WithAge(age int) Option {
 return func(person *Person) {
  person.age = age
 }
}

func WithAddress(addr string) Option {
 return func(person *Person) {
  person.address = addr
 }
}

使用:

func main() {
 newPerson := NewPerson(WithName("John Doe"),
  WithAge(30), WithAddress("Beijing"))
 fmt.Printf("Person: %+v\n", newPerson)
}

優點:①提高代碼的可讀性和靈活性。②避免構造函數參數過多導致的代碼混亂。③允許在運行時動態地配置對象。

應用場景

1)數據庫連接配置:使用函數選項來設置連接參數,如主機、端口、用戶名、密碼等。

2)HTTP 請求配置:使用函數選項來設置請求頭、超時時間、代理等信息。

3)對象構建:使用函數選項來設置對象的屬性,如日誌級別、緩存配置等。

Builder 模式

Builder 模式是一種用於構建複雜對象的設計模式。它將對象的構造過程與對象的表示分離,使得同樣的構建過程可以創建不同的對象。Builder 模式通過定義一個 Builder 接口,以及該接口的具體實現類來逐步構建對象。

實現方式

定義一個 Builder 對象,該對象包含創建目標對象各個部分的方法,以及一個返回最終構建對象的方法。

Builder 對象和實例化:

type PersonBuilder struct {
 name    string
 age     int
 address string
}

func NewPersonBuilder() *PersonBuilder {
 return &PersonBuilder{}
}

Builder 對象的各個方法實現:

func (pb *PersonBuilder) WithName(name string) *PersonBuilder {
 pb.name = name
 return pb
}

func (pb *PersonBuilder) WithAge(age int) *PersonBuilder {
 pb.age = age
 return pb
}

func (pb *PersonBuilder) WithAddress(address string) *PersonBuilder {
 pb.address = address
 return pb
}

Build 方法實現:

func (pb *PersonBuilder) Build() *Person {
 return &Person{
  name:    pb.name,
  age:     pb.age,
  address: pb.address,
 }
}

優點:①可以一步一步地構建對象,使得構建過程更加清晰。②允許在構建過程中進行多種配置,提高了對象的靈活性。③使得代碼更加模塊化,易於維護和擴展。

應用場景

1)構建複雜的配置文件。

2)創建定製化的產品對象。

3)需要逐步構建對象的情況,如構建一臺電腦,其中包含多個組件(CPU、GPU、RAM、硬盤等)。

兩種設計模式的核心思想

Builder 模式的核心思想是將一個複雜對象的構建過程與其表示分離,使得同樣的構建過程可以創建不同的對象。它通過將複雜對象分解爲多個簡單的部分,然後一步一步構建而成。

Builder 模式的優點在於封裝性好,構建和表示分離。其次是擴展性好,各個具體的建造者相互獨立,有利於系統的解耦。客戶端不必知道產品內部組成的細節,建造者可以對創建過程逐步細化,而不對其他模塊產生任何影響,便於控制細節風險。但缺點是如果產品的內部變化複雜,建造者也要同步修改,後期維護成本較大。

Options 模式(也稱爲函數選項模式)允許使用可變構造函數構建複雜結構,該構造函數可以接受零個或多個函數作爲參數。這些函數選項用於設置對象的可選

其優點是提供了靈活和可擴展的方式來配置類的實例,無需改變構造函數簽名。調用者只需要關注他們關心的選項,忽略其他默認配置,提高了代碼的可讀性和可維護性。新增選項不需要更改構造函數的簽名,對舊代碼無影響。適合於有多個配置選項的情況,可以輕鬆地添加或修改實例的配置,同時保持代碼的簡潔性。

本質上的不同

關注點:Builder 模式關注於將複雜對象的構建過程分解和封裝,而 Options 模式則關注於提供靈活的配置選項來構建對象。

結構複雜度:Builder 模式通常涉及多個角色(產品、抽象建造者、具體建造者、指揮者),而 Options 模式則相對簡單,主要包含一個結構體和一些函數選項。

使用場景:Builder 模式更適合於需要精確控制對象構建過程和組件的複雜場景,而 Options 模式則更適合於需要靈活配置多個選項的簡單或中等複雜度的對象。

小總結

Optional 模式和 Builder 模式都是 Go 語言中用於對象構建和配置的重要設計模式。Optional 模式通過函數選項提供靈活的配置選項,適用於參數較少且相對簡單的情況。而 Builder 模式則通過逐步構建對象並提供多種配置選項,適用於構建複雜對象的情況。在選擇使用哪種模式時,應根據具體需求和對象複雜程度進行權衡。

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