概述
仍然使用上一篇簡單工廠模式中的例子,在水果農場中,FruitFactory
可以返回具體的水果實例,包括🍎和🍊等等,但是如果這個水果農場新增了一種水果,比如🍉,那麼我們除了新增🍉類以外,還需要修改FruitFactory
的代碼,使得整個設計違反了開閉原則。
因此我們不再使用一個FruitFactory
來統一負責所有水果實例的創建,而是交給專門的工廠子類去完成,相當於我們把水果農場拆分成了🍎廠和🍊廠等等。
工廠方法模式:定義一個用於創建對象的接口,但是讓子類決定將哪一個類實例化,工廠方法模式讓一個類的實例化延遲到其子類。
使用頻率:★★★★★
結構與實現
相對於簡單工廠模式,工廠方法模式將Factory(工廠角色)拆分成了
- Factory(抽象工廠角色)
- ConcreteFactory(具體工廠角色)
另外還包括
- Product (抽象產品角色)
- ConcreteProduct (具體產品角色)
一共4種角色。
實現上,ConcreteProduct 和 Product 角色與簡單工廠模式一樣,區別在於 Factory 和 ConcreteFactory 角色。
interface FruitFatory
{
public Fruit GetFruit();
}
class AppleFactory : FruitFatory
{
public Fruit GetFruit()
{
return new Apple();
}
}
客戶端調用方式也發生變化,需要先指定具體工廠角色。
static void Main(string[] args)
{
FruitFatory fruitFatory = new AppleFactory();
Fruit fruit = fruitFatory.GetFruit();
fruit.MethodSame();
fruit.MethodDiff();
}
在這樣的結構中,我們增加🍉類時就不需要修改FruitFactory
中的代碼,而是增加一個專門生產🍉的工廠類,遵循了開閉原則。
優缺點
優點:
- 提供了專門的工廠方法來創建客戶所需要的產品,同時還向客戶隱藏了那種具體產品類將被實例化這一細節。客戶只需要關心所需產品對應的工廠即可。
- 基於工廠角色和產品角色的多態性設計是此模式的關鍵。能夠讓工廠自主決定創建何種產品對象,而如何創建這個對象的細節完全封裝在具體工廠內部。
- 再系統中加入新產品時,完全符合開閉原則。
缺點:
- 添加新產品時,類的個數將成對增加,增加系統複雜度。
- 引入抽象層增加理解難度。
適用場景
- 客戶端不知道它所需要的對象的類。
- 抽象工廠類通過其子類來指定創建哪個對象。