2.1. 模式動機
現(xiàn)在對該系統(tǒng)進行修改天通,不再設(shè)計一個按鈕工廠類來統(tǒng)一負(fù)責(zé)所有產(chǎn)品的創(chuàng)建,而是將具體按鈕的創(chuàng)建過程交給專門的工廠子類去完成,我們先定義一個抽象的按鈕工廠類嘁扼,再定義具體的工廠類來生成圓形按鈕抑胎、矩形按鈕、菱形按鈕等,它們實現(xiàn)在抽象按鈕工廠類中定義的方法驾荣。這種抽象化的結(jié)果使這種結(jié)構(gòu)可以在不修改具體工廠類的情況下引進新的產(chǎn)品,如果出現(xiàn)新的按鈕類型嫂伞,只需要為這種新類型的按鈕創(chuàng)建一個具體的工廠類就可以獲得該新按鈕的實例掖棉,這一特點無疑使得工廠方法模式具有超越簡單工廠模式的優(yōu)越性,更加符合“開閉原則”蒂窒。
2.2. 模式定義
工廠方法模式(Factory Method Pattern)又稱為工廠模式躁倒,也叫虛擬構(gòu)造器(Virtual Constructor)模式或者多態(tài)工廠(Polymorphic Factory)模式,它屬于類創(chuàng)建型模式洒琢。在工廠方法模式中秧秉,工廠父類負(fù)責(zé)定義創(chuàng)建產(chǎn)品對象的公共接口,而工廠子類則負(fù)責(zé)生成具體的產(chǎn)品對象衰抑,這樣做的目的是將產(chǎn)品類的實例化操作延遲到工廠子類中完成象迎,即通過工廠子類來確定究竟應(yīng)該實例化哪一個具體產(chǎn)品類。
2.3. 模式結(jié)構(gòu)
工廠方法模式包含如下角色:
Product:抽象產(chǎn)品
ConcreteProduct:具體產(chǎn)品
Factory:抽象工廠
ConcreteFactory:具體工廠
2.4. 代碼分析
工廠方法模式使用子類的方式延遲生成對象到子類中實現(xiàn)呛踊。
Go中不存在繼承 所以使用匿名組合來實現(xiàn)
package factorymethod
//Operator 是被封裝的實際類接口
type Operator interface {
? SetA(int)
? SetB(int)
? Result() int
}
//OperatorBase 是Operator 接口實現(xiàn)的基類砾淌,封裝公用方法
type OperatorBase struct {
? a, b int
}
//SetA 設(shè)置 A
func (o *OperatorBase) SetA(a int) {
? o.a = a
}
//SetB 設(shè)置 B
func (o *OperatorBase) SetB(b int) {
? o.b = b
}
//OperatorFactory 是工廠接口
type OperatorFactory interface {
? Create() Operator
}
//PlusOperatorFactory 是 PlusOperator 的工廠類
type PlusOperatorFactory struct{}
func (PlusOperatorFactory) Create() Operator {
? return &PlusOperator{
? ? ? OperatorBase: &OperatorBase{},
? }
}
//PlusOperator Operator 的實際加法實現(xiàn)
type PlusOperator struct {
? *OperatorBase
}
//Result 獲取結(jié)果
func (o PlusOperator) Result() int {
? return o.a + o.b
}
//MinusOperatorFactory 是 MinusOperator 的工廠類
type MinusOperatorFactory struct{}
func (MinusOperatorFactory) Create() Operator {
? return &MinusOperator{
? ? ? OperatorBase: &OperatorBase{},
? }
}
//MinusOperator Operator 的實際減法實現(xiàn)
type MinusOperator struct {
? *OperatorBase
}
//Result 獲取結(jié)果
func (o MinusOperator) Result() int {
? return o.a - o.b
}
package factorymethod
import "testing"
func compute(factory OperatorFactory, a, b int) int {
? op := factory.Create()
? op.SetA(a)
? op.SetB(b)
? return op.Result()
}
func TestOperator(t *testing.T) {
? var (
? ? ? factory OperatorFactory
? )
? factory = PlusOperatorFactory{}
? if compute(factory, 1, 2) != 3 {
? ? ? t.Fatal("error with factory method pattern")
? }
? factory = MinusOperatorFactory{}
? if compute(factory, 4, 2) != 2 {
? ? ? t.Fatal("error with factory method pattern")
? }
}