漫谈设计模式之抽象工厂模式(Abstract Factory)

什么是抽象工厂模式?抽象工厂模式和工厂方法模式一样都是属于创建型设计模式。抽象工厂为创建一组相关的或相互依赖的对象提供一个接口,而无需指定它们具体的类。

抽象工厂模式与工厂方法模式的区别:抽象工厂模式是工厂方法模式的升级版本,它用来创建一组相关的或者相互依赖的对象,而工厂方法模式只能创建某一个具体的对象。它与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对多个产品等级结构。通常一个产品结构表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或者抽象类。

在抽象工厂模式中,有一个产品族的概念:所谓的产品族,是指位于不同产品结构中功能相关联的产品组成的家族。抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构。

漫谈设计模式之抽象工厂模式(Abstract Factory)_第1张图片


从上面的产品族和产品等级结构中我们可以看出:工厂方法模式只能生产一个产品(要么生产香蕉,要么生产苹果),但是不能同时生产一个产品族。抽象工厂能同时生产一个产品族。

解释:工厂模式在符合开闭原则下,能生产香蕉/苹果(产品等级结构)。具体示例代码见: 

漫谈设计模式之工厂方法模式(Factory Method);

抽象工厂在符合开闭原则下,能生产南方香蕉/南方苹果(产品族)。具体代码示例见下文。


总结重要区别:工厂方法模式只能生产一个产品(要么香蕉、要么苹果),抽象工厂可以一下生产一个产品族(里面有很多产品组成)。


抽象工厂的类结构图:

漫谈设计模式之抽象工厂模式(Abstract Factory)_第2张图片

抽象工厂模式的优点:抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。所谓的产品族一般或多或少都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联进行定义和描述,而不必专门引入一个新的类来进行管理。


抽象工厂模式的缺点:产品族的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。


使用场景:当需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。说的更明白一点,就是一个继承体系中,如果存在着多个等级结构(及存在着多个抽象类),并且分属各个等级结构中的实现类之间存在着一定的关联或者约束,就可以使用抽象工厂模式。假如各个等级结构中的实现类之间不存在关联或约束,则使用多个独立的工厂来对产品进行创建,则更合适一点。


总结:无论是简单工厂模式,工厂方法模式还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦合。在使用时,我们不必去在意这个模式到底是工厂方法模式还是抽象工厂方法模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的是工厂方法模式,当新需求来临时,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使得产品不再构成产品族之后,它就演变成了工厂方法模式。所以在使用工厂方法模式时,只需要关心降低耦合度的目的是否达到了。


抽象工厂示例代码:

#include 

using namespace std;

//前置声明
class Fruit;

/**
 * @brief The AbstractFactory class
 * 抽象工厂类可以生产两种(或多种)产品
 */
class AbstractFactory
{
public:
    virtual ~AbstractFactory(){}
    virtual Fruit* createBanana()=0;
    virtual Fruit* createApple()=0;
};

/**
 * @brief The Fruit class
 * 抽象产品类提供抽象接口供具体产品类重写
 */
class Fruit
{
public:
    virtual ~Fruit(){}
    virtual void getFruit()=0;

};

/**
 * @brief The NorthBanana class
 * 具体产品类实现抽象产品类提供的接口
 */
class NorthBanana : public Fruit
{
public:
    virtual void getFruit() {
        cout<<"Iam NorthBanana,enjoy me~\n";
    }
};

/**
 * @brief The NorthApple class
 * 具体产品类实现抽象产品类提供的接口
 */
class NorthApple : public Fruit
{
public:
    virtual void getFruit() {
        cout<<"Iam NorthApple,enjoy me~\n";
    }
};

/**
 * @brief The SouthBanana class
 * *具体产品类实现抽象产品类提供的接口
 */
class SouthBanana : public Fruit
{
public:
    virtual void getFruit() {
        cout<<"Iam SouthBanana,enjoy me~\n";
    }

};

/**
 * @brief The SouthApple class
 * 具体产品类实现抽象产品类提供的接口
 */
class SouthApple : public Fruit
{
public:
    virtual void getFruit() {
        cout<<"Iam SouthApple,enjoy me~\n";
    }
};

/**
 * @brief The NorthFactory class
 * 具体工厂类实现抽象工厂提供的接口
 */
class NorthFactory : public AbstractFactory
{
public:
    virtual Fruit* createBanana() {
        return new NorthBanana;
    }

    virtual Fruit* createApple() {
        return new NorthApple;
    }
};

/**
 * @brief The SouthFactory class
 * 具体工厂类实现抽象工厂提供的接口
 */
class SouthFactory : public AbstractFactory
{
public:
    virtual Fruit* createBanana() {
        return new SouthBanana;
    }

    virtual Fruit* createApple() {
        return new SouthApple;
    }
};


int main()
{
    AbstractFactory* abstractFactory = NULL;
    Fruit* fruit = NULL; //抽象产品

    //用北方工厂生产北方的香蕉和北方的苹果
    abstractFactory = new NorthFactory;
    fruit = abstractFactory->createBanana();
    fruit->getFruit();
    delete fruit;
    fruit = NULL;
    fruit = abstractFactory->createApple();
    fruit->getFruit();
    delete fruit;
    fruit = NULL;

    delete abstractFactory;
    abstractFactory = NULL;


    //用南方工厂生产南方的香蕉和南方的苹果
    abstractFactory = new SouthFactory;
    fruit = abstractFactory->createBanana();
    fruit->getFruit();
    delete fruit;
    fruit = NULL;
    fruit = abstractFactory->createApple();
    fruit->getFruit();
    delete fruit;
    fruit = NULL;

    delete abstractFactory;
    abstractFactory = NULL;


    return 0;
}


运行结果:

漫谈设计模式之抽象工厂模式(Abstract Factory)_第3张图片


Enjoy Coding~


你可能感兴趣的:(抽象工厂方法,C++,设计模式,设计模式)