介绍
工厂方法是一种创建型
设计模式, 解决了在不指定具体类的情况下创建产品对象的问题。
工厂方法定义了一个方法, 且必须使用该方法代替通过直接调用构造函数来创建对象(new操作符)的方式。 子类可重写该方法来更改将被创建的对象所属类。
说明
在本例中, 我们将使用工厂结构体来构建多种类型的车辆。
首先, 我们来创建一个名为 iCar的接口, 其中将定义一辆车所需具备的所有方法。 然后是实现了 iCar 接口的car结构体类型。 两种具体的车辆—— bmw与 benz ——两者都嵌入了车辆结构体, 且间接实现了所有的 iCar 方法。
carFactory枪支工厂结构体将发挥工厂的作用, 即通过传入参数构建所需类型的车辆。 main.go 则扮演着客户端的角色。 其不会直接与 bmw 或 benz 进行互动, 而是依靠 carFactory来创建多种枪支的实例, 仅使用字符参数来控制生产。
代码
iCar.go: 产品接口
1
2
3
4
5
6
7
8
|
package main
type iCar interface {
setName(name string)
setPower(power int)
getName() string
getPower() int
}
|
car.go: 具体产品
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
package main
type car struct {
name string
power int
}
func (g *car) setName(name string) {
g.name = name
}
func (g *car) getName() string {
return g.name
}
func (g *car) setPower(power int) {
g.power = power
}
func (g *car) getPower() int {
return g.power
}
|
bmw.go: 具体产品
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
package main
type bmw struct {
car
}
func newbmw() iCar {
return &bmw{
car: car{
name: "bmw car",
power: 4,
},
}
}
|
benz.go: 具体产品
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
package main
type benz struct {
car
}
func newbenz() iCar {
return &benz{
car: car{
name: "benz car",
power: 1,
},
}
}
|
carFactory.go: 工厂
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package main
import "fmt"
func getcar(carType string) (iCar, error) {
if carType == "bmw" {
return newbmw(), nil
}
if carType == "benz" {
return newbenz(), nil
}
return nil, fmt.Errorf("Wrong car type passed")
}
|
main.go: 客户端代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
package main
import "fmt"
func main() {
bmw, _ := getcar("bmw")
benz, _ := getcar("benz")
printDetails(bmw)
printDetails(benz)
}
func printDetails(g iCar) {
fmt.Printf("car: %s", g.getName())
fmt.Println()
fmt.Printf("Power: %d", g.getPower())
fmt.Println()
}
|
output.txt: 执行结果
1
2
3
4
|
car: bmw car
Power: 4
car: benz car
Power: 1
|