0、工厂模式类型
工厂模式就是用一个单独的类来做创造实例的过程,用来创造的其他实例的这个类即为工厂。工厂模式一般分为三种:简单工厂模式、工厂方法模式、抽象工厂模式。
1、简单工厂模式
简单工厂模式是属于创建型模式,又叫做静态工厂方法(static Factory Method)模式,简单工厂模式是由一个工厂对象决定创建出来哪一种产品类的实例。简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一类产品类(这些产品类继承自一个父类或接口)的实例。打个比方,假设有一个工厂,他能生产出A、B两种产品。当客户需要产品的时候一定要告诉工厂是哪种产品,是A还是B。当新增加一种新产品的时候,那么就要去修改工厂的类。
例:
#include <iostream>
using namespace std;
class AbstracProduct
{
public:
virtual ~AbstracProduct() {}
virtual void Operation() = 0;
};
class ProductA : public AbstracProduct
{
public:
void Operation() {
cout << "ProductA" << endl;
}
};
class ProductB : public AbstracProduct
{
public:
void Operation() {
cout << "ProductB" << endl;
}
};
class Factory {
public:
AbstracProduct* createProduct(char product) {
AbstracProduct* ap = nullptr;
switch (product)
{
case 'A':
ap = new ProductA();
break;
case 'B':
ap = new ProductB();
break;
default:
break;
}
return ap;
}
};
int main() {
Factory *f = new Factory();
AbstracProduct *apa = f->createProduct('A');
apa->Operation();
AbstracProduct *apb = f->createProduct('B');
apb->Operation();
delete apb;
delete apa;
delete f;
system("pause");
return 0;
}
输出:
2、工厂方法
上面的简单工厂模式的缺点是当新增产品的时候就要去修改工厂的类,这就违反了开放封闭原则,(类、模块、函数)可以扩展,但是不可以修改,于是,就出现了工厂方法模式。所谓工厂方法模式,是指定义一个用于创建对象的接口,让子类决定实例化哪一个类。打个比方现在有A、B两种产品,那么就开两个工厂。工厂A负责生产A产品,工厂B负责生产B种产品。这时候客户不需要告诉工厂生产哪种产品了,只需要告诉工厂生产就可以了。
#include <iostream>
using namespace std;
class AbstracProduct
{
public:
virtual ~AbstracProduct() {}
virtual void Operation() = 0;
};
class ProductA : public AbstracProduct
{
public:
void Operation() {
cout << "ProductA" << endl;
}
};
class ProductB : public AbstracProduct
{
public:
void Operation() {
cout << "ProductB" << endl;
}
};
class Factory {
public:
virtual ~Factory() {}
// 必须用返回AbstracProduct*,即返回父类指针,不能返回AbstracProduct
virtual AbstracProduct* FactoryMethod() = 0;
};
class FactoryA : public Factory
{
public:
AbstracProduct* FactoryMethod() {
return new ProductA();
}
};
class FactoryB : public Factory
{
public:
AbstracProduct* FactoryMethod() {
return new ProductB();
}
};
int main() {
Factory* fa = new FactoryA(); // 用子类实例化父类
AbstracProduct* pa = fa->FactoryMethod(); // 使用此指针返回具体类里的成员函数
pa->Operation();
Factory* fb = new FactoryB();
AbstracProduct* pb = fb->FactoryMethod();
pb->Operation();
delete pb;
delete fb;
delete pa;
delete fa;
system("pause");
return 0;
}
输出:
3、抽象工厂
为什么要有抽象工厂模式,假如我们A产品中有A1和A2两种型号的厂品,B产品中有B1和B2两种型号的厂品,那怎么办,上面两种工厂模式就不能解决了。这个时候抽象工厂模式就登场了。还是开设两家工厂,工厂1负责生产A1 、B1型号产品,2工厂负责生产A2、B2型号的产品。 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 适用性:一个系统要独立于它的产品的创建、组合和表示时。一个系统要由多个产品系列中的一个来配置时。当你要强调一系列相关的产品对象的设计以便进行联合使用时。当你提供一个产品类库,而只想显示它们的接口而不是实现时。
例:
#include <iostream>
using namespace std;
class AbstracProductA
{
public:
virtual ~AbstracProductA() {}
virtual void Operation() = 0;
};
class ProductA1 : public AbstracProductA
{
public:
void Operation() {
cout << "ProductA1" << endl;
}
};
class ProductA2 : public AbstracProductA
{
public:
void Operation() {
cout << "ProductA2" << endl;
}
};
class AbstracProductB
{
public:
virtual ~AbstracProductB() {}
virtual void Operation() = 0;
};
class ProductB1 : public AbstracProductB
{
public:
void Operation() {
cout << "ProductB1" << endl;
}
};
class ProductB2 : public AbstracProductB
{
public:
void Operation() {
cout << "ProductB2" << endl;
}
};
class AbstractFactory {
public:
virtual ~AbstractFactory() {}
virtual AbstracProductA* CreateProductA() = 0;
virtual AbstracProductB* CreateProductB() = 0;
};
class Factory1 : public AbstractFactory
{
public:
ProductA1* CreateProductA() {
return new ProductA1();
}
ProductB1* CreateProductB() {
return new ProductB1;
}
};
class Factory2 : public AbstractFactory
{
public:
ProductA2* CreateProductA() {
return new ProductA2();
}
ProductB2* CreateProductB() {
return new ProductB2;
}
};
int main() {
// 工厂1
AbstractFactory* af1 = new Factory1();
// 工厂1创建产品A1
AbstracProductA* apa1 = af1->CreateProductA();
apa1->Operation();
// 工厂1创建产品B1
AbstracProductB* apb1 = af1->CreateProductB();
apb1->Operation();
// 工厂2
AbstractFactory* af2 = new Factory2();
// 工厂2创建产品A2
AbstracProductA* apa2 = af2->CreateProductA();
apa2->Operation();
// 工厂2创建产品B2
AbstracProductB* apb2 = af2->CreateProductB();
apb2->Operation();
delete apb2;
delete apa2;
delete af2;
delete apb1;
delete apa1;
delete af1;
system("pause");
return 0;
}
输出:
4、抽象工厂函数的优缺点
优点:
- 易于交换产品系列,由于具体工厂类在一个应用中只需要在初始化的时候出现一次,这样就使得改变一个应用的具体工厂变得非常容易,只需要改变具体工厂即可使用不同的产品配置。
- 让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂实现分离,不会出现在客户代码中。
缺点:
增加新的产品时需要改动多处代码。