工廠模式是一種建立型模式,也是最常用的設計模式之一。呼叫方通過工廠產出並獲取物件,可以不必關注物件建立的細節和構建邏輯。
在工廠模式下,呼叫方只和工廠進行互動,並告訴工廠具體獲取哪種型別的物件。工廠負責和相應的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!