Abstract Factory(抽象工厂)模式

1.意图

    提供一个创建一系列相关或相互依赖对象的接口,而无需制定它们具体的类。

2.适用性

  •  一个系统要独立于它的产品创建、组合和表示时。
  • 一个系统要由多个产品系列中的一个来配置时。
  • 当你强调一系列相关的产品对象的设计以便进行联合使用时。
  • 当你提供一个产品的类库,而只想显示它们的接口而不是实现时。

3.结构图

    如上图所示为抽象工厂的结构图,每一个工厂负责创建一系列产品。

4.C++代码实例

#include <cstdlib>
#include <string>
class AbstractFactory;

class Client
{
public:
    Client(){};
    ~Client(){};
    AbstractFactory *GetFactory(std::string type);
private:
    AbstractFactory *pFactory;

};
Client.h
 1 class AbstractProductA
 2 {
 3 public:
 4     AbstractProductA()
 5     {
 6     }
 7     virtual ~AbstractProductA()
 8     {
 9     };
10 };
11 
12 
13 class AbstractProductB
14 {
15 public:
16     AbstractProductB()
17     {
18     }
19     virtual ~AbstractProductB()
20     {
21     };
22 };
AbstractProduct
 1 class AbstractProductA;
 2 class AbstractProductB;
 3 
 4 class AbstractFactory
 5 {
 6 public:
 7      AbstractFactory()
 8      {
 9      };
10      ~AbstractFactory(){};
11     virtual AbstractProductA * CreateProductA()=0;
12     virtual AbstractProductB * CreateProductB()=0;
13 };
AbstractFactory
 1 #include "AbstractFactory.h"
 2 
 3 class AbstractProductA;
 4 class AbstractProductB;
 5 
 6 class ConcreteFactory1 : public AbstractFactory
 7 {
 8 public:
 9     ConcreteFactory1();
10     ~ConcreteFactory1();
11     AbstractProductA * CreateProductA();
12     AbstractProductB * CreateProductB();
13 };
14 
15 class ConcreteFactory2 : public AbstractFactory
16 {
17 public:
18     ConcreteFactory2();
19     ~ConcreteFactory2();
20     AbstractProductA * CreateProductA();
21     AbstractProductB * CreateProductB();
22 };
ConcreteFactory
 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <iostream>
 4 #include "AbstractProduct.h"
 5 
 6 class ConcreteProductA1 : public AbstractProductA
 7 {
 8 public:
 9     ConcreteProductA1()
10     {
11         std::cout << "ConcreteProductA1 is Created" << std::endl;
12     }
13     ~ConcreteProductA1()
14     {
15     }
16 };
17 
18 class ConcreteProductA2 : public AbstractProductA
19 {
20 public:
21     ConcreteProductA2()
22     {
23         std::cout << "ConcreteProductA2 is Created" << std::endl;
24     }
25     ~ConcreteProductA2()
26     {
27     }
28 };
29 
30 class ConcreteProductB1 : public AbstractProductB
31 {
32 public:
33     ConcreteProductB1()
34     {
35         std::cout << "ConcreteProductB1 is Created" << std::endl;
36     }
37 
38     ~ConcreteProductB1()
39     {
40     }
41     
42 };
43 
44 class ConcreteProductB2 : public AbstractProductB
45 {
46 public:
47     ConcreteProductB2()
48     {
49         std::cout << "ConcreteProductB2 is Created" << std::endl;
50     }
51 
52     ~ConcreteProductB2()
53     {
54     }
55 };
ConcereteProduct
#include "ConcreteFactory.h"
#include "ConcreteProduct.h"



ConcreteFactory1::ConcreteFactory1()
{
}

ConcreteFactory1::~ConcreteFactory1()
{
}

AbstractProductA * ConcreteFactory1::CreateProductA()
{
    auto product = new ConcreteProductA1();
    return product;
}

AbstractProductB * ConcreteFactory1::CreateProductB()
{
    auto product = new ConcreteProductB1();
    return product;
}


ConcreteFactory2::ConcreteFactory2()
{
}

ConcreteFactory2::~ConcreteFactory2()
{
}

AbstractProductA * ConcreteFactory2::CreateProductA()
{
    auto product = new ConcreteProductA2();
    return product;
}

AbstractProductB * ConcreteFactory2::CreateProductB()
{
    auto product = new ConcreteProductB2();
    return product;
}
ConcreteFactory.cpp
#include "Client.h"
#include "ConcreteFactory.h"

 AbstractFactory *Client::GetFactory(std::string type)
 {
     if("1" == type)
     {
         auto pFactory = new ConcreteFactory1();
         return pFactory;
     }
     else if ("2" == type)
     {
         auto pFactory = new ConcreteFactory2();
         return pFactory;
     }
 }
Client.cpp
#include "Client.h"
#include "AbstractFactory.h"
#include "AbstractProduct.h"

int main()
{
    auto client = new Client();
    auto pFactory = client->GetFactory("1");
    auto pProductA = pFactory->CreateProductA();
    auto pProductB = pFactory->CreateProductB();
    delete pProductB;
    pProductB = NULL;
    delete pProductA;
    pProductA = NULL;
    delete pFactory;
    pFactory = NULL;

    pFactory = client->GetFactory("2");
    pProductA = pFactory->CreateProductA();
    pProductB = pFactory->CreateProductB();
    delete pProductB;
    pProductB = NULL;
    delete pProductA;
    pProductA = NULL;
    delete pFactory;
    pFactory = NULL;
    delete client;
    client=NULL;

    while(1);
    

}
TestCode.cpp

测试结果:

如测试代码中所写,先创建1系列的产品A和B,后创建2系列的产品A和B。

5.效果

  • 分离了具体的类,产品的类名不出现在测试代码(即客户代码)中。
  • 使得易于交换产品系列。
  • 利于产品的一致性。
  • 难以支持新种类的产品

6.相关模式

抽象工厂类通常用工厂方法实现,但是也可以用原型实现。一个具体的工厂通常是一个单件。

 

原文地址:https://www.cnblogs.com/mgp200866130/p/5398528.html