今天分享另外一种创建型类型的设计模式-简单工厂模式,简单工厂模式简单概括:客户端请求时,通过工厂类的创建接口,传入不同的参数,进而实现返回不同类的实例,可见运用简单工厂模式,是为了获取不同类的实例。
举个例子,有个工厂,生产不同的水果罐头,有代号01的黄桃罐头,代号02的荔枝罐头,代号03的苹果罐头等等,想要哪种罐头,只需要向工厂请求相关代号即可获取对应罐头。
下面详细聊聊简单工厂模式到底是怎样的。
定义
定义一个工厂类,根据传入的参数的值不同,返回不同的实例,所有的实例都由仅有的这个工厂来创建,这样的模式就是简单工厂模式。
特点
被创建的实例具有共同的父类或接口,但是实现类数量多了后,违反开闭原则。
结构
- 1.一个用于创建实例的工厂类
- 2.一个实例接口,声明实现的实例类的方法
- 3.实例类,所有被创建的实例都要实现接口
适用场景
- 1.需要创建的对象比较少。仅创建几个类问题不大,如果数量扩展到数百个,意味着写一堆if else,代码臃肿。
- 2.客户端不关心对象的创建过程。不用了解细节,在需要的地方传入不同参数调用就好了。
优缺点
- 优点
1.可以对创建的对象进行“加工”,对客户端隐藏相关细节。只关注结果,无需了解过程。
2.通过该模式 , 实现了对 创建实例
和使用实例
的责任分割
- 缺点
1.若创建逻辑复杂或创建对象过多,则会造成代码臃肿。
2.新增、删除子类均会违反开闭原则。
3.简单工厂模式的工厂类单一,负责所有产品的创建,职责过重,一旦异常,整个系统将受影响。且工厂类代码会非常臃肿,违背高内聚原则。
代码实现
代码结构:
- 1.创建动物接口,声明
say
方法。 - 2.创建具体动物类,实现接口。
- 3.创建工厂类,提供创建不同动物实例的方法作为外部接口。
- 4.客户端通过工厂类的方法,传入不同参数获取不同动物的实例。
package main
import "fmt"
// 1.define product interface
type animal interface {
say() string
}
// 2.define concrete product struct
type dog struct{}
func (r *dog) say() string {
return "dog say: 汪汪汪"
}
type cat struct{}
func (r cat) say() string {
return "cat say: 喵喵喵"
}
// 3.create simple factory struct
type simpleFactory struct {
}
type animalTyp int
const (
dogTyp animalTyp = iota
catTyp
)
// create instance, seperate creating and using
func (s *simpleFactory) CreateAnimal(typ animalTyp) animal {
switch typ {
case dogTyp:
return &dog{}
case catTyp:
return &cat{}
default:
return &dog{}
}
}
func main() {
factory := simpleFactory{}
d := factory.CreateAnimal(dogTyp)
fmt.Println(d.say())
c := factory.CreateAnimal(catTyp)
fmt.Println(c.say())
}