工厂模式属于结构型模式,能够细分为三种模式:
- 简略工厂模式
- 工厂办法模式
- 形象工厂模式
这三种模式从上到下逐渐形象,在学习工厂模式之前,须要先明确为什么要应用工厂模式。工厂模式对类的实例化过程进行了形象,可能将软件模块中对象的创立和对象的应用拆散。为了能使得代码构造和逻辑更加清晰,外界对于这些对象只须要晓得他们独特的接口,而不须要晓得外部具体的实现逻辑,使得整个零碎的设计更加合乎繁多指摘准则。工厂模式代替new初始化实例对象,这样做的益处是封装了更多的实现细节,能够对对象的生命周期进行更好的治理。
一、简略工厂模式
简略工厂模式是三种模式中最简略的模式、也是最罕用的一种工厂模式。简略工厂模式时有一个工厂来决定创立哪一种实例对象。代码如下:
package factoryimport "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 factoryimport "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)PASSDebugger finished with the exit code 0
上边的程序中,定义了三个构造体,构造体都实现了Phone接口,创立一个工厂模块,工厂模块提供初始化程序,依据传入的参数决定生产苹果、华为还是小米手机。这样在测试用例中,只须要初始化一次工厂,工厂对象创立实例对象即可,创立实例的操作定义在createFactory中即可。
简略工厂模式的优缺点:
- 长处:调用者只须要晓得参数和办法名称即可创建对象,无需晓得外部实现细节,大大不便了调用者的应用。
毛病:毛病很显著--扩展性太差。简略工厂的外围是工厂模块,工厂模块中依据传递的参数来决定创立哪一种对象,很适宜对象类型少且类型固定场景,如果要增加其余的对象除了创立新的构造体、实现接口,还须要批改工厂模块,增加新的分支才能够,这样重大违反了开闭准则,对扩大凋谢、对批改关闭。
二、工厂办法模式
工厂办法模式是对简略工厂模式的进一步形象,工厂办法模式肯定水平上解决了简略工厂模式扩展性不好的问题。具体代码如下:
package methodimport "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 methodimport "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)PASSProcess 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 factoryimport "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 factoryimport "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 factoryimport "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 factoryimport "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)PASSProcess finished with the exit code 0