一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第19天,点击查看活动详情。
简单工厂模式
我们常常使用工厂模式去解决一系列对象的创建的问题,将其封装到一个工厂里,外面使用者不需要知道如何创建的。使用者通过工厂就可以拿到自己想要的对象。所以经常将一些创建起来比较复杂的对象都放在工厂里面,且不是很多的对象,可能就只是几个创建复杂的对象封装成工厂。
只要创建的对象不多,只需要一个工厂类就可以解决问题的,这种模式是简单工厂模式。
首先需要创建一系列产品结构体
type IProduct interface {
create()
}
type Product1 struct {
}
func (pro1 Product1) create() {
fmt.Print("product 。。。1")
}
type Product2 struct {
}
func (pro2 Product2) create() {
fmt.Print("product 。。。2")
}
创建一个工厂结构体,并给工厂加一个可以生成产品的方法,即生成对象的方法
type ClassFactory struct {
}
func (factory *ClassFactory) generProduction(name string) IProduct {
switch name {
case "pro1":
return Product1{}
case "pro2":
return Product2{}
default:
return nil
}
}
创建完之后就可以使用,传入不同的名字得到不用的产品
factory := new(Factory)
p1 := factory.Generate("pro1")
p1.create()
p2 := factory.Generate("pro2")
p2.create()
工厂方法模式
如果有新的不用的产品,就需要建立新的不同的工厂类。当有新的产品的时候都需要修改工厂类,这样就违背了开闭原则。所以进一步优化后,提出了工厂方法模式,根据不同的对象提供不同工厂,使得每个对象都有一个对应的工厂。
// 工厂方法模式
type IFactory interface {
Create(level string) IProduction
}
type Factory1 struct {
}
type IProduction interface {
Info()
}
type Production1 struct {
}
func (pro1 Production1) Info() {
println("production1 info ")
}
type Production2 struct {
}
func (pro1 Production2) Info() {
println("production2 info ")
}
func (f Factory1) Create(level string) IProduction {
switch level {
case "leve1":
return Production1{}
case "leve2":
return Production2{}
}
}
创建后就可以让子类选择实例化什么样产品
f := new(Factory1)
p := f.Create("leve1")
p.Info()
工厂方法模式中,需要有工厂接口(抽象工厂),工厂结构体(具体工厂),产品接口(抽象产品),产品接口体(具体产品)。
可以看出,工厂创建出来的对象不再依赖于具体的产品而是抽象的产品,使得对象从使用中解藕,增加了扩展性。后续可以创建不用工厂造不同的产品。符合依赖倒置原则,依赖抽象不依赖具体。使得使用和实现解藕。