简单工厂模式并不属于GoF的23种设计模式,他是开发者自发认为的一种非常简易的设计模式,其职责如下:

工厂角色:简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。

抽象产品角色:简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。

具体产品角色:简单工厂模式所创建的具体实例对象。

go语言设计模式-简单工厂模式_简单工厂模式

简单工厂的实现:

水果类是抽象的产品,而苹果类、香蕉类、梨类是具体的产品,让需求者(main函数)直接跟水果类和工厂类打交道,而不用跟具体的产品的构造方法show()打交道,也就是说需要对接水果跟工厂要就行了,工厂把水果给你,工厂层将业务层和产品层解耦。

工厂类需要返回抽象的产品,不能返回具体的产品。如果返回具体的产品,代表这个工厂只能生产一种产品,这明显是不符合规定的,工厂是需要生产香蕉、梨等多种水果的。返回的是一个抽象的,最终return的是某个具体的苹果类,香蕉类....用抽象的指针指向具体对象,符合多态的特征(父类指针指向子类对象),父类指针通过调用水果类的具体对象的show方法,依然能够拿到产品。

go语言设计模式-简单工厂模式_简单工厂模式_02

简单工厂类代码实现:

package main

import "fmt"

//---抽象层---
type Fruit interface {
Show() //接口的方法
}

//---实现层---
type Apple struct {
Fruit //为了易于理解,继承父类的属性
}

func (apple *Apple) Show() {
fmt.Println("我是apple")
}

type Banana struct {
Fruit //为了易于理解,继承父类的属性
}

func (banana *Banana) Show() {
fmt.Println("我是banana")
}

type Pear struct {
Fruit //为了易于理解,继承父类的属性
}

func (pear *Pear) Show() {
fmt.Println("我是pear")
}

//---工厂模块---
type Factory struct {
}

func (fac *Factory) CreateFruit(kind string) Fruit {
var fruit Fruit //父的指针
if kind == "apple" {
//apple构造初始化业务
fruit = new(Apple) //满足多态条件的赋值,父的指针指向子的对象
} else if kind == "banana" {
fruit = new(Banana)
} else if kind == "pear" {
fruit = new(Pear)
}

return fruit
}

//---业务逻辑层--- apple,banana,pear如何创建业务层是不需要关注的,全部在CreateFruit实现
func main() {
factory := new(Factory)

apple := factory.CreateFruit("apple") //Fruit类型
apple.Show()

banana := factory.CreateFruit("banana") //Fruit类型
banana.Show()

pear := factory.CreateFruit("pear") //Fruit类型
pear.Show()
}

结果:

我是apple
我是banana
我是pear


简单工厂方法模式的优缺点:

优点:

1 实现了对象的创建和实现的分离。

2 不需要记住类名,记住参数即可,减少使用者的记忆量(上例中的name)。

缺点:

1 对工厂类职责过重,一旦不能工作,系统就会受到影响。

2 增加系统中类的个数,复杂度和理解度增加。

3 违反“开闭原则”,添加新产品需要修改工厂逻辑,工厂越来越复杂,这也是简单工厂模式并不属于GoF的23种设计模式的原因(上例中新增加水果类,需要在CreateFruit的if else逻辑中新增水果类的初始化)。


适用场景:

1 工厂类负责创建的对象比较少,由于创建的对象较少,不会造成工厂方法中的业务逻辑过于复杂。

2 客户端只知道传入工厂类的参数,对于如何创建对象并不关心。