2023-08-22|閱讀時間 ‧ 約 5 分鐘

Golang - Design Pattern #2: 工廠模式 (Factory)

工廠模式 (Factory) 在物件創建中佔有舉足輕重的位置,讓我們能以更模組化的方式管理物件的生成。這篇文章將帶領你深入工廠模式在Go語言中的實踐。


簡介

工廠模式背後的核心思想是將物件創建的邏輯和使用分離,這使得我們的應用能夠更容易地擴展並維護。


實際應用與實現


動物的叫聲

考慮一個需求:我們的系統中有多種動物,每種動物都有自己的叫聲。
type Animal interface {
Speak() string
}

type Dog struct{}
func (d *Dog) Speak() string {
return "Woof!"
}

type Cat struct{}
func (c *Cat) Speak() string {
return "Meow!"
}


支付系統接口

考慮一個更實際的例子:在一個電子商務平台上,我們希望支援多種支付方式。
type PaymentMethod interface {
Pay(amount float64) string
}

type Paypal struct{}
func (p *Paypal) Pay(amount float64) string {
return fmt.Sprintf("Paid %f via Paypal", amount)
}

type CreditCard struct{}
func (c *CreditCard) Pay(amount float64) string {
return fmt.Sprintf("Paid %f using Credit Card", amount)
}


工廠模式 + map

在傳統的工廠模式中,我們可能會使用條件語句(如if或switch)來確定要創建哪種類型的實例。但這樣的做法,每當新增新的類型時,就需要修改工廠的代碼。使用 map 作為工廠可以解決這個問題。

簡單來說,map允許我們將字符串(如 dogpaypal)映射到具體的創建函數。這樣,當需要新增類型時,只需擴展這個 map,而不是修改工廠的主要邏輯。

Animal Factory

Payment Factory

在這個上面的兩個流程圖中,當客戶端呼叫 GetAnimalGetPaymentMethod時,函數內部會查找相應的map以獲得創建函數,然後使用該函數創建並返回相應的實例。


// Animal Map
var AnimalFactory = map[string]func() Animal{
"dog": func() Animal { return &Dog{} },
"cat": func() Animal { return &Cat{} },
}

// Payment Map
var PaymentFactory = map[string]func() PaymentMethod{
"paypal": func() PaymentMethod { return &Paypal{} },
"creditcard": func() PaymentMethod { return &CreditCard{} },
}

// Animal Factory
func GetAnimal(t string) Animal {
if factory, ok := AnimalFactory[t]; ok {
return factory()
}
return nil
}

// Payment Factory
func GetPaymentMethod(method string) PaymentMethod {
if factory, ok := PaymentFactory[method]; ok {
return factory()
}
return nil
}


func main() {
animal := GetAnimal("dog")
fmt.Println(animal.Speak()) // Woof!

payment := GetPaymentMethod("paypal")
fmt.Println(payment.Pay(100.5)) // Paid 100.5 via Paypal
}


結語

通過使用map進行工廠模式的實現,我們可以更加靈活地新增物件類型,而無需修改現有代碼。此外,這種方式還簡化了我們的工廠邏輯。希望這兩個實際的例子能幫助你更好地理解工廠模式在Go中的應用,並在實際開發中靈活使用!🚀

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.