抽象工厂模式(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


标签: none

添加新评论