工厂模式属于结构型模式,可以细分为三种模式:
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
这三种模式从上到下逐步抽象,在学习工厂模式之前,需要先明白为什么要使用工厂模式。工厂模式对类的实例化过程进行了抽象,能够将软件模块中对象的创建和对象的使用分离。为了能使得代码结构和逻辑更加清晰,外界对于这些对象只需要知道他们共同的接口,而不需要知道内部具体的实现逻辑,使得整个系统的设计更加符合单一指责原则。工厂模式代替new初始化实例对象,这样做的好处是封装了更多的实现细节,可以对对象的生命周期进行更好的管理。
一、简单工厂模式
简单工厂模式是三种模式中最简单的模式、也是最常用的一种工厂模式。简单工厂模式时有一个工厂来决定创建哪一种实例对象。代码如下:
package factory
import "fmt"
type Phone interface {
Show()
}
// ----------实现层逻辑------------
type Apple struct {
Phone
}
func (a *Apple) Show() {
fmt.Println("苹果手机")
}
type Huawei struct {
Phone
}
func (h *Huawei) Show() {
fmt.Println("华为手机")
}
type Xiaomi struct {
Phone
}
func (x *Xiaomi) Show() {
fmt.Println("小米手机")
}
// ----------工厂模块------------
type Factory struct {
}
func (f *Factory) createFruit(kind string) Phone {
var phone Phone
switch kind {
case "apple":
phone = new(Apple)
case "huawei":
phone = new(Huawei)
case "xiaomi":
phone = new(Xiaomi)
}
return phone
}
测试用例
package factory
import "testing"
func TestFactory(t *testing.T) {
factory := new(Factory)
apple := factory.createFruit("apple")
apple.Show()
huawei := factory.createFruit("huawei")
huawei.Show()
xiaomi := factory.createFruit("xiaomi")
xiaomi.Show()
}
执行结果
=== RUN TestFactory
苹果手机
华为手机
小米手机
--- PASS: TestFactory (2.11s)
PASS
Debugger finished with the exit code 0
上边的程序中,定义了三个结构体,结构体都实现了Phone接口,创建一个工厂模块,工厂模块提供初始化程序,根据传入的参数决定生产苹果、华为还是小米手机。这样在测试用例中,只需要初始化一次工厂,工厂对象创建实例对象即可,创建实例的操作定义在createFactory中即可。
简单工厂模式的优缺点:
- 优点:调用者只需要知道参数和方法名称即可创建对象,无需知道内部实现细节,大大方便了调用者的使用。
缺点:缺点很明显--扩展性太差。简单工厂的核心是工厂模块,工厂模块中根据传递的参数来决定创建哪一种对象,很适合对象类型少且类型固定场景,如果要添加其他的对象除了创建新的结构体、实现接口,还需要修改工厂模块,添加新的分支才可以,这样严重违背了开闭原则,对扩展开放、对修改封闭。
二、工厂方法模式
工厂方法模式是对简单工厂模式的进一步抽象,工厂方法模式一定程度上解决了简单工厂模式扩展性不好的问题。具体代码如下:
package method import "fmt" // ----------抽象层------------ type Phone interface { Show() } type AbstractFactory interface { ProductPhone() Phone // 一定要返回Phone接口 } // ----------实现层逻辑------------ type Apple struct { Phone } func (a *Apple) Show() { fmt.Println("苹果手机") } type Huawei struct { Phone } func (h *Huawei) Show() { fmt.Println("华为手机") } type Xiaomi struct { Phone } func (x *Xiaomi) Show() { fmt.Println("小米手机") } // ----------具体工厂逻辑------------ type AppleFactory struct{} func (a *AppleFactory) ProductPhone() Phone { var phone Phone phone = new(Apple) return phone } type HuaweiFactory struct{} func (h *HuaweiFactory) ProductPhone() Phone { var phone Phone phone = new(Huawei) return phone } type XiaomiFactory struct{} func (a *XiaomiFactory) ProductPhone() Phone { var phone Phone phone = new(Xiaomi) return phone } // 测试程序 package method import "testing" func TestAppleFactory_ProductPhone(t *testing.T) { // 苹果手机工厂 var appleFac AbstractFactory appleFac = new(AppleFactory) var apple Phone apple = appleFac.ProductPhone() apple.Show() // 华为手机工厂 var huaweiFac AbstractFactory huaweiFac = new(HuaweiFactory) var huawei Phone huawei = huaweiFac.ProductPhone() huawei.Show() // 小米手机工厂 var xiaomiFac AbstractFactory xiaomiFac = new(XiaomiFactory) var xiaomi Phone xiaomi = xiaomiFac.ProductPhone() xiaomi.Show() }
运行结果
=== RUN TestAppleFactory_ProductPhone 苹果手机 华为手机 小米手机 --- PASS: TestAppleFactory_ProductPhone (0.00s) PASS Process finished with the exit code 0
工厂方法模式有几个核心模块:
- 抽象层: 抽象出对外提供需要被调用的接口。
- 具体工厂层:这一层为创建具体对象的层级,每一中对象都对应一个专门的工厂来生产。
- 实现逻辑层:具体的实现,创建对象后的业务逻辑封装在这一层级。
工厂方法模式的优缺点:
- 优点:工厂方法模式把简单工厂的单一工厂改为多个工厂,原来是父类生产所有类型的对象,现在是把生产对象的逻辑下放都具体的子类,由子类来控制。这样的话,如果有新的类型进来,只需要在实现逻辑层添加一个结构体,在具体工厂层创建对应的工厂即可,可以根据需要添加,而无需修改原有的代码,这样就很好的遵循了开闭原则,实现了解藕。
- 缺点:添加一个类型就需要创建两个结构体,如果添加的类型很多,就会大大增加系统复杂性,也不易理解。
三、抽象工厂模式
抽象工厂模式针对产品镞是符合开闭原则的,但对产品等级结构不是符合开闭原则的,适合产品镞比较多且产品等级结构很稳定的场景下使用。代码如下:
定义抽象逻辑:
package factory
// ----------抽象逻辑------------
type Phone interface {
ShowPhone()
}
type Computer interface {
ShowComputer()
}
type HeadPhone interface {
ShowHeadPhone()
}
type AbstractFactory interface {
ProductPhone() Phone
ProductComputer() Computer
ProductHeadPhone() HeadPhone
}
定义华为产品镞实现层:
package factory
import "fmt"
// ----------实现层逻辑------------
type HuaweiPhone struct{}
func (h *HuaweiPhone) ShowPhone() {
fmt.Println("华为手机")
}
type HuaweiComputer struct {
}
func (h *HuaweiComputer) ShowComputer() {
fmt.Println("华为电脑")
}
type HuaweiHeadPhone struct {
}
func (h *HuaweiHeadPhone) ShowHeadPhone() {
fmt.Println("华为耳机")
}
type HuaweiFactory struct {
}
func (h *HuaweiFactory) ProductPhone() Phone {
var phone Phone
phone = new(HuaweiPhone)
return phone
}
func (h *HuaweiFactory) ProductComputer() Computer {
var computer Computer
computer = new(HuaweiComputer)
return computer
}
func (h *HuaweiFactory) ProductHeadPhone() HeadPhone {
var headPhone HeadPhone
headPhone = new(HuaweiHeadPhone)
return headPhone
}
定义苹果产品镞实现层:
package factory
import "fmt"
// ----------实现层逻辑------------
type ApplePhone struct{}
func (h *ApplePhone) ShowPhone() {
fmt.Println("苹果手机")
}
type AppleComputer struct {
}
func (h *AppleComputer) ShowComputer() {
fmt.Println("苹果电脑")
}
type AppleHeadPhone struct {
}
func (h *AppleHeadPhone) ShowHeadPhone() {
fmt.Println("苹果耳机")
}
type AppleFactory struct {
}
func (h *AppleFactory) ProductPhone() Phone {
var phone Phone
phone = new(ApplePhone)
return phone
}
func (h *AppleFactory) ProductComputer() Computer {
var computer Computer
computer = new(AppleComputer)
return computer
}
func (h *AppleFactory) ProductHeadPhone() HeadPhone {
var headPhone HeadPhone
headPhone = new(AppleHeadPhone)
return headPhone
}
定义小米产品镞实现层:
package factory
import "fmt"
// ----------实现层逻辑------------
type XiaomiPhone struct{}
func (h *XiaomiPhone) ShowPhone() {
fmt.Println("小米手机")
}
type XiaomiComputer struct {
}
func (h *XiaomiComputer) ShowComputer() {
fmt.Println("小米电脑")
}
type XiaomiHeadPhone struct {
}
func (h *XiaomiHeadPhone) ShowHeadPhone() {
fmt.Println("小米耳机")
}
type XiaomiFactory struct {
}
func (h *XiaomiFactory) ProductPhone() Phone {
var phone Phone
phone = new(XiaomiPhone)
return phone
}
func (h *XiaomiFactory) ProductComputer() Computer {
var computer Computer
computer = new(XiaomiComputer)
return computer
}
func (h *XiaomiFactory) ProductHeadPhone() HeadPhone {
var headPhone HeadPhone
headPhone = new(XiaomiHeadPhone)
return headPhone
}
测试程序:
package factory
import "testing"
func TestFactory(t *testing.T) {
// 华为
var hf AbstractFactory
hf = new(HuaweiFactory)
hf.ProductPhone().ShowPhone()
hf.ProductHeadPhone().ShowHeadPhone()
hf.ProductComputer().ShowComputer()
// 苹果
var af AbstractFactory
af = new(AppleFactory)
af.ProductPhone().ShowPhone()
af.ProductHeadPhone().ShowHeadPhone()
af.ProductComputer().ShowComputer()
// 小米
var xf AbstractFactory
xf = new(AppleFactory)
xf.ProductPhone().ShowPhone()
xf.ProductHeadPhone().ShowHeadPhone()
xf.ProductComputer().ShowComputer()
}
运行结果:
=== RUN TestFactory
华为手机
华为耳机
华为电脑
苹果手机
苹果耳机
苹果电脑
苹果手机
苹果耳机
苹果电脑
--- PASS: TestFactory (0.00s)
PASS
Process finished with the exit code 0
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。