天天看点

设计模式 - AbstractFactory抽象工厂

1.简单描述

抽象工厂包含两部分:一是继承自同一个抽象类的产品类族;二是不同类型的抽象工厂。抽象工厂中可以创建该类产品所需要的元素(创建产品类的数据成员),而生产的所有元素便是抽象工厂的产物。由于抽象工厂可以生成许多元素,所以我们又可以认为,抽象工厂是封装了多个工厂方法,对于每一个元素就相当于一个工厂方法。到底是哪一种类型的元素则由具体的工厂类型决定(子类决定)。产品不再作为抽象工厂的直接输出产物,而是使用工厂的输出组合而成,所以产品可以更加抽象不用再区分大类(大类由抽象工厂决定)。

2.类图

。。。。。。。。

待补

3.实例程序

3.1 元素定义

#ifndef Ingredient_H
#define Ingredient_H

#include <string>
#include <iostream>


class IngredientA
{
public:
    virtual void printIngredientName() = 0;
};

class IngredientA1: public IngredientA
{
    void printIngredientName()
    {
        std::cout<<"IngredientA1"<<std::endl;
    }
};

class IngredientA2: public IngredientA
{
    void printIngredientName()
    {
        std::cout<<"IngredientA2"<<std::endl;
    }
};

class IngredientB
{
public:
    virtual void printIngredientName() = 0;
};

class IngredientB1: public IngredientB
{
    void printIngredientName()
    {
        std::cout<<"IngredientB1"<<std::endl;
    }
};

class IngredientB2: public IngredientB
{
    void printIngredientName()
    {
        std::cout<<"IngredientB2"<<std::endl;
    }
};

#endif
           

3.2 产品定义

// product.h
#ifndef Product_H
#define Product_H

#include "Ingredient.h"

class AbstractFactory;
class Product
{
public:
	Product(){};
    virtual ~Product(){};
    virtual void printProductName() = 0;
};

class ProductA: public Product
{
public:
    ProductA(const AbstractFactory& factory);
	virtual ~ProductA(){};
    virtual void printProductName();

private:
    IngredientA* m_pIA;
    // IngredientB* m_pIB;
};

class ProductB: public Product
{
public:
    ProductB(const AbstractFactory& factory);
	virtual ~ProductB(){};
    virtual void printProductName();

private:
    IngredientA* m_pIA;
    IngredientB* m_pIB;
};

#endif
           
// product.cpp
#include "stdafx.h"
#include <iostream>
#include "Product.h"
#include "AbstractFactory.h"
using namespace std;

ProductA::ProductA(const AbstractFactory& factory)
{
    m_pIA = factory.createIngredientA();
}

void ProductA::printProductName()
{
    cout<<"ProductA->";
    if (NULL != m_pIA)
    {
        m_pIA->printIngredientName();
    }
}

ProductB::ProductB(const AbstractFactory& factory)
{
    m_pIA = factory.createIngredientA();
    m_pIB = factory.createIngredientB();
}

void ProductB::printProductName()
{
    cout<<"ProductB->";
    if (NULL != m_pIB)
    {
        m_pIB->printIngredientName();
    }
    cout<<"ProductB->";
    if (NULL != m_pIA)
    {
        m_pIA->printIngredientName();
    }
}
           

3.3 工厂定义

// factory,h
#ifndef AbstractFactory_H
#define AbstractFactory_H

#include "Ingredient.h"

class AbstractFactory
{
public:
    virtual IngredientA* createIngredientA() const = 0;
    virtual IngredientB* createIngredientB() const = 0;
};

class AbstractFactoryA: public AbstractFactory
{
public:
	AbstractFactoryA(){};
	~AbstractFactoryA(){};
    virtual  IngredientA* createIngredientA() const;
    virtual  IngredientB* createIngredientB() const;
};

class AbstractFactoryB: public AbstractFactory
{
public:
	AbstractFactoryB(){};
	~AbstractFactoryB(){};
    virtual IngredientA* createIngredientA() const;
    virtual IngredientB* createIngredientB() const;
};

#endif
           
// factory.cpp
#include "stdafx.h"
#include "AbstractFactory.h"

IngredientA* AbstractFactoryA::createIngredientA() const
{
    return new IngredientA1();
}

IngredientB* AbstractFactoryA::createIngredientB() const
{
    return new IngredientB1();
}


IngredientA* AbstractFactoryB::createIngredientA() const
{
    return new IngredientA2();
}

IngredientB* AbstractFactoryB::createIngredientB() const
{
    return new IngredientB2();
}
           

3.4 测试程序

// test.cpp
#include <iostream>
#include "AbstractFactory.h"
#include "Product.h"
using namespace std;

int main(int argc, char const *argv[])
{
    /* code */
    AbstractFactoryA factoryA;
    AbstractFactory& factory1 = factoryA;
    Product* produce1 = new ProductA(factory1);
    if (NULL != produce1)
    {
        produce1->printProductName();
        delete produce1;
        produce1 = NULL;
    }
    produce1 = new ProductB(factory1);
    if (NULL != produce1)
    {
        produce1->printProductName();
        delete produce1;
        produce1 = NULL;
    }

    AbstractFactoryB factoryB;
    factory1 = factoryB;
    produce1 = new ProductA(factory1);
    if (NULL != produce1)
    {
        produce1->printProductName();
        delete produce1;
        produce1 = NULL;
    }
    produce1 = new ProductB(factory1);
    if (NULL != produce1)
    {
        produce1->printProductName();
        delete produce1;
        produce1 = NULL;
    }
    
    return 0;
}
           

4.扩展分析

4.1 产品扩展

1.对于普通工厂模式,新增产品需要扩充产品子类,在一个或多个工厂类中加入新扩充产品的创建。 2.对于抽象工厂模式,新增产品只需要扩充产品子类,新产品可有老元素组合而成,工厂类不用变化,也不会加减。

4.2 产品元素扩展

1.对于普通工厂模式,需要修改所有加入新元素的类。 2.对于抽象工厂模式,需要修改所有加入新元素的类,同时修改需要生成该元素的工厂。

继续阅读