你的位置:首页 > ASP.net教程

[ASP.net教程]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 AbstractProductB14 {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 AbstractFactory16 {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 AbstractProductA19 {20 public:21   ConcreteProductA2()22   {23     std::cout << "ConcreteProductA2 is Created" << std::endl;24   }25   ~ConcreteProductA2()26   {27   }28 };29 30 class ConcreteProductB1 : public AbstractProductB31 {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 AbstractProductB45 {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.相关模式

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