(1)定義
簡單工廠模式中,每新增一個具體産品,就需要修改工廠類内部的判斷邏輯。為了不修改工廠類,遵循開閉原則,工廠方法模式中不再使用工廠類統一建立所有的具體産品,而是針對不同的産品設計了不同的工廠,每一個工廠隻生産特定的産品。
定義一個用于建立對象的接口,但是讓子類決定将哪一個類執行個體化。工廠方法模式讓一個類的執行個體化延遲到其子類。
(2)結構
工廠模式結構如下:
- 抽象工廠(AbstractFactory):所有生産具體産品的工廠類的基類,提供工廠類的公共方法;
- 具體工廠(ConcreteFactory):生産具體的産品;
- 抽象産品(AbstractProduct):所有産品的基類,提***品類的公共方法;
- 具體産品(ConcreteProduct):具體的産品類。
(3)執行個體
Factory.h
#ifndef FACTORY_H
#define FACTORY_H
#include <iostream>
#include <string>
/********************************産品類***********************************/
//抽象産品類AbstractProduct(并非真正意義上的抽象類,含有純虛函數才是抽象類)
class AbstractSportProduct
{
public:
AbstractSportProduct(){}
~AbstractSportProduct(){}
//虛函數
virtual void play(){}
};
//具體産品類Basketball
class Basketball :public AbstractSportProduct
{
public:
Basketball(){}
~Basketball(){}
//具體實作方法
void play();
};
//具體産品類Football
class Football :public AbstractSportProduct
{
public:
Football(){}
~Football(){}
//具體實作方法
void play();
};
/********************************工廠類***********************************/
//抽象工廠類
class AbstractFactory{
public:
//純虛函數
virtual AbstractSportProduct *getSportProduct() = 0;
};
//具體工廠類BasketballFactory
class BasketballFactory:public AbstractFactory
{
public:
BasketballFactory(){}
~BasketballFactory(){}
AbstractSportProduct *getSportProduct();
};
//具體工廠類FootballFactory
class FootballFactory:public AbstractFactory
{
public:
FootballFactory(){}
~FootballFactory(){}
AbstractSportProduct *getSportProduct();
};
#endif // FACTORY_H
Factory.cpp
#include "Factory.h"
/********************************産品類方法***********************************/
//Basketball方法
void Basketball::play(){
printf("play Basketball\n");
}
//Football方法
void Football::play(){
printf("play Football\n");
}
/********************************工廠類方法***********************************/
//BasketballFactory方法
AbstractSportProduct *BasketballFactory::getSportProduct()
{
return new Basketball();
}
//FootballFactory方法
AbstractSportProduct *FootballFactory::getSportProduct()
{
return new Football();
}
main.cpp
#include "Factory.h"
int _tmain(int argc, _TCHAR* argv[])
{
AbstractSportProduct *pro = nullptr;
AbstractFactory *fac = nullptr;
fac = new BasketballFactory();
pro = fac->getSportProduct();
pro->play();
fac = new FootballFactory();
pro = fac->getSportProduct();
pro->play();
return 0;
}
輸出結果:
(4)總結
如果想增加棒球(Baseball)類,隻需要增加一個棒球工廠(BaseballFacory),然後在用戶端代碼中修改具體工廠類的類名,而原有的類的代碼無需修改。由此可看到,相較簡單工廠模式,工廠方法模式更加符合開閉原則。工廠方法是使用頻率最高的設計模式之一,是很多開源架構和API類庫的核心模式。
優點:
- 工廠方法用于建立客戶所需産品,同時向客戶隐藏某個具體産品類将被執行個體化的細節,使用者隻需關心所需産品對應的工廠;
- 工廠自主決定建立何種産品,并且建立過程封裝在具體工廠對象内部,多态性設計是工廠方法模式的關鍵;
- 新加入産品時,無需修改原有代碼,增強了系統的可擴充性,符合開閉原則。
缺點:
- 添加新産品時,需要同時添加新的産品工廠,系統中類的數量成對增加,增加了系統的複雜度,更多的類需要編譯和運作,增加了系統的額外開銷;
- 工廠和産品都引入了抽象層,用戶端代碼中均使用的抽象層,增加了系統的抽象層次和了解難度。