C++ 工廠方法模式 - BBA 各造各的車

工廠方法模式(Factory Method Pattern)是一種常用的對(duì)象創(chuàng)建型設(shè)計(jì)模式,此模式的核心思想是封裝類中不變的部分,提取其中個(gè)性化善變的部分為獨(dú)立類,通過依賴注入以達(dá)到解耦、復(fù)用以及方便后期維護(hù)拓展的目的。
1
模式結(jié)構(gòu)
UML 結(jié)構(gòu)圖:

Factory(抽象工廠):是工廠方法模式的核心,與應(yīng)用程序無關(guān)。任何在模式中創(chuàng)建的對(duì)象的工廠類必須實(shí)現(xiàn)這個(gè)接口。
ConcreteFactory(具體工廠):實(shí)現(xiàn)抽象工廠接口的具體工廠類,包含與應(yīng)用程序密切相關(guān)的邏輯,并且被應(yīng)用程序調(diào)用以創(chuàng)建產(chǎn)品對(duì)象。
Product(抽象產(chǎn)品):所創(chuàng)建對(duì)象的基類,也就是具體產(chǎn)品的共同父類或共同擁有的接口。
ConcreteProduct(具體產(chǎn)品):實(shí)現(xiàn)了抽象產(chǎn)品角色所定義的接口。某具體產(chǎn)品有專門的具體工廠創(chuàng)建,它們之間往往一一對(duì)應(yīng)。
2
優(yōu)缺點(diǎn)
克服了簡單工廠模式違背開放-封閉原則的缺點(diǎn),又保留了封裝對(duì)象創(chuàng)建過程的優(yōu)點(diǎn),降低客戶端和工廠的耦合性。所以說,“工廠方法模式”是“簡單工廠模式”的進(jìn)一步抽象和推廣。
每增加一個(gè)產(chǎn)品,相應(yīng)的也要增加一個(gè)子工廠,加大了額外的開發(fā)量。
3
適用場景
對(duì)于某個(gè)產(chǎn)品,調(diào)用者清楚地知道應(yīng)該使用哪個(gè)具體工廠服務(wù),實(shí)例化該具體工廠,生產(chǎn)出具體的產(chǎn)品來。
只是需要一種產(chǎn)品,而不想知道也不需要知道究竟是哪個(gè)工廠生產(chǎn)的,即最終選用哪個(gè)具體工廠的決定權(quán)在生產(chǎn)者一方,它們根據(jù)當(dāng)前系統(tǒng)的情況來實(shí)例化一個(gè)具體的工廠返回給使用者,而這個(gè)決策過程對(duì)于使用者來說是透明的。
4
案例分析
工廠模式基本和簡單工廠模式差不多,簡單工廠模式 - 在產(chǎn)品子類添加時(shí),需要添加一個(gè)判斷分支,這違背了開放-封閉原則。因此,工廠模式就是為了解決這個(gè)問題而產(chǎn)生的。

所以,對(duì)于《C++ 簡單工廠模式 - BBA 造車了》一節(jié)中的 BBA 來說,要分別由對(duì)應(yīng)的工廠來生產(chǎn)。
5
代碼實(shí)現(xiàn)
汽車產(chǎn)品,由 ICar 表示:
// product.h
#ifndef PRODUCT_H
#define PRODUCT_H
#include <string>
using namespace std;
// 汽車接口
class ICar
{
public:
virtual string Name() = 0; // 汽車名稱
};
#endif // PRODUCT_H
模型有了,就可以定義具體的汽車了,它們有不同的品牌:
// concrete_product.h
#ifndef CONCRETE_PRODUCT_H
#define CONCRETE_PRODUCT_H
#include "product.h"
// 奔馳汽車
class BenzCar : public ICar
{
public:
string Name() override {
return "Benz Car";
}
};
// 寶馬汽車
class BmwCar : public ICar
{
public:
string Name() override {
return "Bmw Car";
}
};
// 奧迪汽車
class AudiCar : public ICar
{
public:
string Name() override {
return "Audi Car";
}
};
#endif // CONCRETE_PRODUCT_H
產(chǎn)品有了,當(dāng)然要有相應(yīng)的工廠來生產(chǎn),但在這之前,需要一個(gè)抽象工廠:
// factory.h
#ifndef FACTORY_H
#define FACTORY_H
#include "product.h"
// 工廠接口
class IFactory
{
public:
virtual ICar* CreateCar() = 0; // 生產(chǎn)汽車
};
#endif // FACTORY_H
為每個(gè)制造商創(chuàng)建對(duì)應(yīng)的的工廠:
// concrete_factory.h
#ifndef CONCRETE_FACTORY_H
#define CONCRETE_FACTORY_H
#include "factory.h"
#include "concrete_product.h"
// 奔馳工廠
class BenzFactory : public IFactory
{
public:
ICar* CreateCar() override {
return new BenzCar();
}
};
// 寶馬工廠
class BmwFactory : public IFactory
{
public:
ICar* CreateCar() override {
return new BmwCar();
}
};
// 奧迪工廠
class AudiFactory : public IFactory
{
public:
ICar* CreateCar() override {
return new AudiCar();
}
};
#endif // CONCRETE_FACTORY_H
這樣以來,每個(gè)工廠只負(fù)責(zé)生產(chǎn)自己的產(chǎn)品。
當(dāng)一切準(zhǔn)備就緒,就可以實(shí)現(xiàn)客戶端了:
// main.cpp
#include "concrete_factory.h"
#include "product.h"
#include <iostream>
#ifndef SAFE_DELETE
#define SAFE_DELETE(p) { if(p){delete(p); (p)=nullptr;} }
#endif
int main()
{
// 奔馳
IFactory *pBenzFactory = new BenzFactory();
ICar *pBenzCar = pBenzFactory->CreateCar();
cout << "Benz Factory: " << pBenzCar->Name() << endl;
// 寶馬
IFactory *pBmwFactory = new BmwFactory();
ICar *pBmwCar = pBmwFactory->CreateCar();
cout << "Bmw Factory: " << pBmwCar->Name() << endl;
// 奧迪
IFactory *pAudiFactory = new AudiFactory();
ICar *pAudiCar = pAudiFactory->CreateCar();
cout << "Audi Factory: " << pAudiCar->Name() << endl;
SAFE_DELETE(pAudiCar);
SAFE_DELETE(pAudiFactory);
SAFE_DELETE(pBmwCar);
SAFE_DELETE(pBmwFactory);
SAFE_DELETE(pBenzCar);
SAFE_DELETE(pBenzFactory);
getchar();
return 0;
}
輸出如下:
Benz Factory: Benz Car
Bmw Factory: Bmw Car
Audi Factory: Audi Car
·················· END ··················
關(guān)注后回復(fù)「1024」,獲取海量學(xué)習(xí)資源

