设计模式--创建型-AbstractFactory(抽象工厂)
1. 意图
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
2. 结构图
3. 简述
客户只知道一个抽象工厂类(AbstractFactory)和由它所创建的一系列产品组件的虚接口(如AbstractProductA等)。而并不知道具体的实现类,包括具体的工厂实现类(如ConcreteFactory1)和具体的产品组件类(如ProductA1)。
抽象工厂(AbstractFactory)和它创建的抽象产品(AbstractProduct)通常被设计成纯虚函数,作为对外界的接口,可以尽可能的减少暴露的信息。这个模式被广泛应用,比如微软的很多基于COM的SDK都采用了这种模式。比如Direct3D 9中的IDirect3DDevice9就是个抽象工厂,我们只能看到这个抽象接口,而并不知道内部的具体实现类。通过这个抽象工厂能创建一系列组件,比如通过CreateTexture创建一个IDirect3DTexture9,通过CreateVertexBuffer创建一个IDirect3DVertexBuffer9等。
和工厂方法(FactoryMethod)的区别。抽象工厂是个类,它能创建一系列相关的具体产品实例,比如上面说的IDirect3DDevice9接口如果需要重建,那么由它所创建的一系列接口(如IDirect3DTexture9、IDirect3DVertexBuffer9等等)都要重建。而工厂方法是指一个成员函数,它只能创建一个具体产品实例。所以,抽象工厂中的每个创建产品实例的成员方法(比如CreateProductA和CreateProductB)都是工厂方法。
4. 实例代码
4.1 对外的接口的定义,给客户Client使用
// 抽象产品组件类A
class AbstractProductA
{
public:
virtual ~AbstractProductA() {}
virtual void FunA() = 0;
};
// 抽象产品组件类B
class AbstractProductB
{
public:
virtual ~AbstractProductB() {}
virtual void FunB() = 0;
};
// 抽象工厂
class AbstractFactory
{
public:
virtual ~AbstractFactory() {}
virtual AbstractProductA* CreateProductA() = 0;
virtual AbstractProductB* CreateProductB() = 0;
};
4.2 内部的实现类,外部无法看到
// 抽象产品组件类A的一个实现类
class ConcreteProductA1 : public AbstractProductA
{
public:
ConcreteProductA1() {}
~ConcreteProductA1() {}
void FunA() {}
};
// 抽象产品组件类B的一个实现类
class ConcreteProductB1 : public AbstractProductB
{
public:
ConcreteProductB1() {}
~ConcreteProductB1() {}
void FunB() {}
};
// 抽象工厂的一个实现类
class ConcreteFactory1 : public AbstractFactory
{
public:
ConcreteFactory1() {}
~ConcreteFactory1() {}
AbstractProductA* CreateProductA()
{
return new ConcreteProductA1;
}
AbstractProductB* CreateProductB()
{
return new ConcreteProductB1;
}
};
4.3 客户程序
int main()
{
AbstractFactory *pFactory = new ConcreteFactory1;
AbstractProductA *pProductA = pFactory->CreateProductA();
pProductA->FunA();
AbstractProductB *pProductB = pFactory->CreateProductB();
pProductB->FunB();
}