C++ 抽象工厂模式 - BBA 造汽车和摩托车啦
抽象工厂模式(Abstract Factory Pattern)是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
1
模式结构
UML 结构图:
Factory(抽象工厂):声明一个用于创建抽象产品的接口
ConcreteFactory(具体工厂):用于创建具体的产品
Product(抽象产品):声明一个产品对象类型的接口
ConcreteProduct(具体产品):由具体工厂创建的具体产品
2
优缺点
优点:
封装了产品的创建,使得不需要知道具体是哪种产品,只需要知道是哪个工厂即可。
可以支持不同类型的产品,使得模式灵活性更强。
可以非常方便的使用一族中的不同类型的产品。
缺点:
结构过于臃肿,如果产品类型较多或产品族较多,会非常难于管理。
每次如果添加一组产品,那么所有的工厂类都必须添加一个方法,这样违背了开放-封闭原则。所以一般适用于产品组合产品族变化不大的情况。
3
适用场景
在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
4
案例分析
BBA - 既造汽车,又造摩托车
《C++ 工厂方法模式 - BBA 各造各的车》要求产品为同一类型的(汽车),倘若要生产其他产品(例如:摩托车),则需要再创建对应的工厂。如果这样的话,后续工厂会越来越多,非常难以管理了。
为了解决这个问题,我们可以扩大现有工厂的规模,增加一条生产线,专门用来生产摩托车,这样就不用新增工厂了,也便于后续的管理。
这就是抽象工厂模式,其根本思想就是将产品归类分组,然后将好几组产品构成一族。每个工厂负责生产一族产品,而工厂中的每个方法负责生产一种类型的产品。
5
代码实现
创建抽象产品
汽车和摩托车产品,分别由 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
创建具体产品
模型有了,就可以定义具体的产品了:
// 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
创建抽象工厂
产品有了,当然要有相应的制造商与其相关联。所以呢,要有具体的工厂。但在这之前,需要一个抽象工厂:
// factory.h
#ifndef FACTORY_H
#define FACTORY_H
#include "product.h"
// 抽象工厂
class IFactory
{
public:
virtual ICar* CreateCar() = 0; // 生产汽车
virtual IMotorcycle* CreateMotorcycle() = 0; // 生产摩托车
};
#endif // FACTORY_H
创建具体工厂
为每个制造商创建具体的工厂:
// 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
这样一来,具体的产品就与其制造商关联起来了。
创建客户端
当一切准备就绪,就可以实现客户端了,利用相关产品的这种层次结构来创建产品。
// 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