簡介
模式定義
在工廠方法模式中,工廠父類負責定義建立産品對象的公共接口,而工廠子類則負責生成具體的産品對象。工廠方法模式讓類的執行個體化延遲到子類中。
模式特點
工廠方法模式包含四個角色:
- Product:抽象産品
- ConcreteProduct:具體産品
- Factory:抽象工廠
- ConcreteFactory:具體工廠
優缺點
- 克服了簡單工廠的缺點,符合開放封閉原則。添加新産品時隻需要添加具體的工廠類,而不需修改抽象工廠
- 添加新對象時,需要同時增加對象類和工廠類
- 用法複雜,抽象工廠在實作時可能需要使用反射技術
- 符合開閉原則,增加産品時隻需要增加一個具體工廠類
執行個體化的類可能會新增類型時,通常使用工廠模式作為建立對象的标準方式。
PHP 代碼示例
<?php
abstract class AbstractButtonFactory
{
abstract public function getInstance();
}
class CircleButtonFactory extends AbstractButtonFactory
{
public function getInstance()
{
return new CircleButton();
}
}
class RectButtonFactory extends AbstractButtonFactory
{
public function getInstance()
{
return new RectButton();
}
}
abstract class AbstractButton
{
abstract public function click();
}
class CircleButton extends AbstractButton
{
public function click()
{
echo "I'm circle button";
}
}
class RectButton extends AbstractButton
{
public function click()
{
echo "I'm rectangle button";
}
}
$cbf = new CircleButtonFactory();
$circleButton = $cbf->getInstance();
$circleButton->click();
Golang 示例
package main
import "fmt"
type Spliter interface {
Split()
}
// type SplitFactory struct {}
// func (sf *SplitFactory) CreateSplit() Spliter {
// // 編譯時依賴,仍然是緊耦合,隻有接口才能運作時綁定,實作晚綁定
// return new(TxtSplit)
// }
type SplitFactory interface {
CreateSplit() Spliter
}
type TxtSplit struct {}
func (s *TxtSplit) Split() {
fmt.Println("TxtSplit Split")
}
type TxtSplitFactory struct {}
func (tsf *TxtSplitFactory) CreateSplit() Spliter {
return new(TxtSplit)
}
type BinSplit struct {}
func (s *BinSplit) Split() {
fmt.Println("BinSplit Split")
}
type BinSplitFactory struct {}
func (tsf *BinSplitFactory) CreateSplit() Spliter {
return new(BinSplit)
}
func main() {
// 預設構造方法,緊耦合
var s Spliter
s = new(BinSplit)
s.Split()
// 通過工廠解耦,此時工廠裡有緊耦合
// sf := &SplitFactory{}
// s2 := sf.CreateSplit()
// s2.Split()
// 通過具體工廠解耦
tsf := new(TxtSplitFactory)
s3 := tsf.CreateSplit()
s3.Split()
}