抽象工厂模式
1、背景
工厂方法模式最后讲到,工厂方法模式的缺点是如果产品种类过多,需要生产大量的工厂类。
同时,由于每个产品种类还分产品族,比如,汽车品牌大众的产品组有跑车类型、家庭类型和商用类型的车;奔驰也有跑车类型、家庭类型和商用类型的车…那么大众、奔驰和其他品牌的想同类型(比如跑车类型)的车可以组成一个产品组跑车类型。
注意
- 相同主题的概念,表示的是同一个产品族,不能将汽车工厂,面粉工厂封装成一个工厂,因为他们不属于同一个产品族;
- 产品等级的概念,以生产汽车为例,所谓的产品等级指的是不同厂商生产的汽车零部件,如大众和奔驰的汽车发动机,他们是同一个产品等级,如果只涉及产品等级的话,是不需要应用抽象工厂模式,使用工厂方法模式即可;
工厂方法模式解决的范畴是产品等级(大众汽车发动机,奔驰汽车发动机等);抽象工厂模式解决的范畴是产品族等级(大众汽车、奔驰汽车等);
2、定义
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
- 运行时刻创建一个ConcreteFactory类的实例,这个具体的工厂再创建具有特定实现的产品对象,也就是说,为创建不同的产品对象,客户端应使用不同的具体工厂。
- 1、抽象工厂(Abstract Factory)角色:担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。
- 2、具体工厂(Concrete Factory)角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。
- 3、抽象产品(Abstract Product)角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。
- 4、具体产品(Concrete Product)角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。
3、特征
1、优点:
- 最大的好处便是易于交换产品系列,由于具体工厂类在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。我们的设计不能去防止需求的更改,那么我们的理想便是让改动变得最小,现在如果你要更改不同的产品,我们只需要更改具体工厂就可以做到。
- 概括就是:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
- 第二大好处是,它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
2、缺点:
- 不容易扩展新的产品等级,比如我要加一个轮胎什么的。那么就需要修改抽象工厂,这样就会导致修改所有的工厂实现类。
3、应用场景
- 当系统所提供的工厂所需生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构中属于不同类型的具体产品时需要使用抽象工厂模式。
- 系统中有多于一个的产品族,而每次只使用其中某一产品族。
- 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现
- 假如各个等级结构中的实现类之间不存在关联或约束,则使用多个独立的工厂来对产品进行创建,则更合适一点。
4、应用
1、抽象工厂模型案例
#include <iostream>
using namespace std;
// 抽象产品A
class ProductA
{
public:
virtual void Show() = 0;
};
//具体产品A1
class ProductA1 : public ProductA
{
public:
void Show()
{
cout << "I'm ProductA1" << endl;
}
};
//具体产品A2
class ProductA2 : public ProductA
{
public:
void Show()
{
cout << "I'm ProductA2" << endl;
}
};
// 抽象产品 B
class ProductB
{
public:
virtual void Show() = 0;
};
//具体产品B1
class ProductB1 : public ProductB
{
public:
void Show()
{
cout << "I'm ProductB1" << endl;
}
};
//具体产品B2
class ProductB2 : public ProductB
{
public:
void Show()
{
cout << "I'm ProductB2" << endl;
}
};
// 抽象工厂
class Factory
{
public:
virtual ProductA *CreateProductA() = 0;
virtual ProductB *CreateProductB() = 0;
};
//具体工厂1
class Factory1 : public Factory
{
public:
ProductA *CreateProductA()
{
return new ProductA1();
}
ProductB *CreateProductB()
{
return new ProductB1();
}
};
//具体工厂2
class Factory2 : public Factory
{
ProductA *CreateProductA()
{
return new ProductA2();
}
ProductB *CreateProductB()
{
return new ProductB2();
}
};
int main(int argc, char *argv[])
{
Factory *factoryObj1 = new Factory1();
ProductA *productObjA1 = factoryObj1->CreateProductA();
ProductB *productObjB1 = factoryObj1->CreateProductB();
productObjA1->Show();
productObjB1->Show();
Factory *factoryObj2 = new Factory2();
ProductA *productObjA2 = factoryObj2->CreateProductA();
ProductB *productObjB2 = factoryObj2->CreateProductB();
productObjA2->Show();
productObjB2->Show();
if (factoryObj1 != NULL)
{
delete factoryObj1;
factoryObj1 = NULL;
}
if (productObjA1 != NULL)
{
delete productObjA1;
productObjA1 = NULL;
}
if (productObjB1 != NULL)
{
delete productObjB1;
productObjB1 = NULL;
}
if (factoryObj2 != NULL)
{
delete factoryObj2;
factoryObj2 = NULL;
}
if (productObjA2 != NULL)
{
delete productObjA2;
productObjA2 = NULL;
}
if (productObjB2 != NULL)
{
delete productObjB2;
productObjB2 = NULL;
}
}
参考
1、https://www.cnblogs.com/Vae1990Silence/p/4379996.html
2、《大话设计模式 》