工廠模式是一種建立型模式,也是最常用的設計模式之一。呼叫方通過工廠產出並獲取物件,可以不必關注物件建立的細節和構建邏輯。
在工廠模式下,呼叫方只和工廠進行互動,並告訴工廠具體獲取哪種型別的物件。工廠負責和相應的struct互動,並返回需要的物件。
如下是工廠模式的UML類圖:
接下來是一個工廠模式的範例,在這個例子中:
- 提供了一個介面
iGun
,定義了一把槍應該有的各種方法 - 提供了一個名為
gun
的類,並實現了iGun
介面 - 兩個具體類
ak47
和maverick
(卡賓槍,一種突擊步槍),兩者都組裝了gun
struct,實現了iGun
的的各種方法,因此它們也可以說是iGun
的子類, - 核心是名為
gunFactory
的struct,它可以產出ak47
和maverick
的例項。 - 最後,是
main.go
檔案及其中的main()
方法,可以被視為是呼叫方,它依賴了gunFactory
來建立ak47
和maverick
的例項,並應用這兩個例項。
這裡是這個例子對應的類圖:
具體程式碼如下:
iGun.go
package main type iGun interface { setName(name string) setPower(power int) getName() string getPower() int }
gun.go
package main type gun struct { name string power int } func (g *gun) setName(name string) { g.name = name } func (g *gun) getName() string { return g.name } func (g *gun) setPower(power int) { g.power = power } func (g *gun) getPower() int { return g.power }
ak47.go
package main type ak47 struct { gun } func newAk47() iGun { return &ak47{ gun: gun{ name: "AK47 gun", power: 4, }, } }
maverick.go
package main type maverick struct { gun } func newMaverick() iGun { return &maverick{ gun: gun{ name: "Maverick gun", power: 5, }, } }
gunFactory.go
package main import "fmt" func getGun(gunType string) (iGun, error) { if gunType == "ak47" { return newAk47(), nil } if gunType == "maverick" { return newMaverick(), nil } return nil, fmt.Errorf("Wrong gun type passed") }
main.go
package main import "fmt" func main() { ak47, _ := getGun("ak47") maverick, _ := getGun("maverick") printDetails(ak47) printDetails(maverick) } func printDetails(g iGun) { fmt.Printf("Gun: %s", g.getName()) fmt.Println() fmt.Printf("Power: %d", g.getPower()) fmt.Println() }
程式碼已上傳至GitHub:zhyea / go-patterns / factory-pattern
End!