C++ 抽象工廠模式 - BBA 造汽車和摩托車啦

抽象工廠模式(Abstract Factory Pattern)是所有形態(tài)的工廠模式中最為抽象和最具一般性的一種形態(tài)。抽象工廠模式是指當有多個抽象角色時,使用的一種工廠模式。抽象工廠模式可以向客戶端提供一個接口,使客戶端在不必指定產(chǎn)品的具體的情況下,創(chuàng)建多個產(chǎn)品族中的產(chǎn)品對象。
1
模式結(jié)構(gòu)
UML 結(jié)構(gòu)圖:

Factory(抽象工廠):聲明一個用于創(chuàng)建抽象產(chǎn)品的接口
ConcreteFactory(具體工廠):用于創(chuàng)建具體的產(chǎn)品
Product(抽象產(chǎn)品):聲明一個產(chǎn)品對象類型的接口
ConcreteProduct(具體產(chǎn)品):由具體工廠創(chuàng)建的具體產(chǎn)品
2
優(yōu)缺點
封裝了產(chǎn)品的創(chuàng)建,使得不需要知道具體是哪種產(chǎn)品,只需要知道是哪個工廠即可。
可以支持不同類型的產(chǎn)品,使得模式靈活性更強。
可以非常方便的使用一族中的不同類型的產(chǎn)品。
結(jié)構(gòu)過于臃腫,如果產(chǎn)品類型較多或產(chǎn)品族較多,會非常難于管理。
每次如果添加一組產(chǎn)品,那么所有的工廠類都必須添加一個方法,這樣違背了開放-封閉原則。所以一般適用于產(chǎn)品組合產(chǎn)品族變化不大的情況。
3
適用場景
在不必指定產(chǎn)品的具體的情況下,創(chuàng)建多個產(chǎn)品族中的產(chǎn)品對象。
4
案例分析
BBA - 既造汽車,又造摩托車

《C++ 工廠方法模式 - BBA 各造各的車》要求產(chǎn)品為同一類型的(汽車),倘若要生產(chǎn)其他產(chǎn)品(例如:摩托車),則需要再創(chuàng)建對應(yīng)的工廠。如果這樣的話,后續(xù)工廠會越來越多,非常難以管理了。
為了解決這個問題,我們可以擴大現(xiàn)有工廠的規(guī)模,增加一條生產(chǎn)線,專門用來生產(chǎn)摩托車,這樣就不用新增工廠了,也便于后續(xù)的管理。
這就是抽象工廠模式,其根本思想就是將產(chǎn)品歸類分組,然后將好幾組產(chǎn)品構(gòu)成一族。每個工廠負責生產(chǎn)一族產(chǎn)品,而工廠中的每個方法負責生產(chǎn)一種類型的產(chǎn)品。
5
代碼實現(xiàn)
汽車和摩托車產(chǎn)品,分別由 ICar 和 IMotorcycle 表示:
// product.h
#ifndef PRODUCT_H
#define PRODUCT_H
#include <string>
using namespace std;
// 汽車接口
class ICar
{
public:
virtual string Name() = 0; // 汽車名稱
};
// 摩托車接口
class IMotorcycle
{
public:
virtual string Name() = 0; // 摩托車名稱
};
#endif // PRODUCT_H
模型有了,就可以定義具體的產(chǎn)品了:
// 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:
std::string Name() override {
return "Audi Car";
}
};
/********** 摩托車 **********/
// 奔馳
class BenzMotorcycle : public IMotorcycle
{
public:
string Name() override {
return "Benz Motorcycle";
}
};
// 寶馬
class BmwMotorcycle : public IMotorcycle
{
public:
string Name() override {
return "Bmw Motorcycle";
}
};
// 奧迪
class AudiMotorcycle : public IMotorcycle
{
public:
string Name() override {
return "Audi Motorcycle";
}
};
#endif // CONCRETE_PRODUCT_H
產(chǎn)品有了,當然要有相應(yīng)的制造商與其相關(guān)聯(lián)。所以呢,要有具體的工廠。但在這之前,需要一個抽象工廠:
// factory.h
#ifndef FACTORY_H
#define FACTORY_H
#include "product.h"
// 抽象工廠
class IFactory
{
public:
virtual ICar* CreateCar() = 0; // 生產(chǎn)汽車
virtual IMotorcycle* CreateMotorcycle() = 0; // 生產(chǎn)摩托車
};
#endif // FACTORY_H
為每個制造商創(chuà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();
}
IMotorcycle* CreateMotorcycle() override {
return new BenzMotorcycle();
}
};
// 寶馬工廠
class BmwFactory : public IFactory
{
public:
ICar* CreateCar() override {
return new BmwCar();
}
IMotorcycle* CreateMotorcycle() override {
return new BmwMotorcycle();
}
};
// 奧迪工廠
class AudiFactory : public IFactory
{
public:
ICar* CreateCar() override {
return new AudiCar();
}
IMotorcycle* CreateMotorcycle() override {
return new AudiMotorcycle();
}
};
#endif // CONCRETE_FACTORY_H
這樣一來,具體的產(chǎn)品就與其制造商關(guān)聯(lián)起來了。
當一切準備就緒,就可以實現(xiàn)客戶端了,利用相關(guān)產(chǎn)品的這種層次結(jié)構(gòu)來創(chuàng)建產(chǎn)品。
// main.cpp
#include "concrete_factory.h"
#include "product.h"
#include <iostream>
using namespace std;
#ifndef SAFE_DELETE
#define SAFE_DELETE(p) { if(p){delete(p); (p)=nullptr;} }
#endif
int main()
{
// 奔馳
IFactory *pBenzFactory = new BenzFactory();
ICar *pBenzCar = pBenzFactory->CreateCar();
IMotorcycle *pBenzMotorcycle = pBenzFactory->CreateMotorcycle();
// 寶馬
IFactory *pBmwFactory = new BmwFactory();
ICar *pBmwCar = pBmwFactory->CreateCar();
IMotorcycle *pBmwMotorcycle = pBmwFactory->CreateMotorcycle();
// 奧迪
IFactory *pAudiFactory = new AudiFactory();
ICar *pAudiCar = pAudiFactory->CreateCar();
IMotorcycle *pAudiMotorcycle = pAudiFactory->CreateMotorcycle();
cout << "Benz factory - Car: " << pBenzCar->Name() << endl;
cout << "Benz factory - Motorcycle: " << pBenzMotorcycle->Name() << endl;
cout << "Bmw factory - Car: " << pBmwCar->Name() << endl;
cout << "Bmw factory - Motorcycle: " << pBmwMotorcycle->Name() << endl;
cout << "Audi factory - Car: " << pAudiCar->Name() << endl;
cout << "Audi factory - Motorcycle: " << pAudiMotorcycle->Name() << endl;
SAFE_DELETE(pBenzCar);
SAFE_DELETE(pBenzMotorcycle);
SAFE_DELETE(pBenzFactory);
SAFE_DELETE(pBmwCar);
SAFE_DELETE(pBmwMotorcycle);
SAFE_DELETE(pBmwFactory);
SAFE_DELETE(pAudiCar);
SAFE_DELETE(pAudiMotorcycle);
SAFE_DELETE(pAudiFactory);
getchar();
return 0;
}
輸出如下:
Benz factory - Car: Benz Car
Benz factory - Motorcycle: Benz Motorcycle
Bmw factory - Car: Bmw Car
Bmw factory - Motorcycle: Bmw Motorcycle
Audi factory - Car: Audi Car
Audi factory - Motorcycle: Audi Motorcycle
·················· END ··················
關(guān)注后回復(fù)「1024」,獲取海量學習資源

