工廠模式是一種創建型模式,也是最常用的設計模式之一。調用方通過工廠產出並獲取對象,可以不必關注對象創建的細節和構建邏輯。
在工廠模式下,調用方只和工廠進行交互,並告訴工廠具體獲取哪種類型的對象。工廠負責和相應的struct交互,並返回需要的對象。
如下是工廠模式的UML類圖:

接下來是一個工廠模式的范例,在這個例子中:
- 提供了一個接口
iGun,定義了一把槍應該有的各種方法 - 提供了一個名為
gun的類,並實現了iGun接口 - 兩個具體類
ak47和maverick(卡賓槍,一種突擊步槍),兩者都組裝了gunstruct,實現了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!
