解决的问题:解决接口选择的问题
使用的场景:明确的计划不同条件下创建不同的实例时;一般应用与多种同类型类的情况,将这些类隐藏起来,再提供统一的接口,便于维护和修改;
解决的方法:让子类实现工厂接口,返回的也是一个抽象的铲平
关键的代码:创建过程在子类中执行
-
优点:
1、一个调用者想创建一个对象时,只需要知道其名称就可以了;
2、扩展性高,如果想增加一个产品,值需要扩展一个工厂类就可以;
3、屏蔽产品的具体实现,调用者只关心产品的接口。 -
缺点:
1、每增加一个产品,需要增加一个具体类和对象实现工厂,使得系统中个数成倍增加,一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖;
2、每添加一个产品子类,都必须在工厂类中添加一个判断分支,这违背了开放-封闭原则。
工厂模式.PNG
-
实例:
举个例子,现在有宝马车和奔驰车两种车需要生产,但是只有一个工厂,且只能在同一时间生产一种车,这时就有工厂决定生产那种车了。例子虽然不是十分恰当,但是会其意即可。我们直接看UML类图和代码吧。
案例.PNG - 代码实现
#include <iostream>
using namespace std;
enum CarType
{
BENZ,
BMW
};
class Car //车类
{
public:
virtual void createCar(void) = 0; //纯虚函数
//纯虚函数
/* 什么是纯虚函数(pure virtual function):
*1、当想在积累中抽象出一个方法,且该基类只能被继承,而不能被实例化
*2、这个方法必须在派生类中实现
};
class BenzCar:public Car //奔驰
{
public:
BenzCar()
{
cout<<"BenzCar---奔驰"<<endl;
}
virtual void createCar(void)
{
cout<<"BenzCar::createCar"<<endl;
}
};
class BmwCar:public Car //宝马
{
public:
BmwCar()
{
cout<<"BmwCar---宝马"<<endl;
}
virtual void createCar(void)
{
cout<<"BmwCar::createCar"<<endl;
}
};
class CarFactory //车厂
{
public:
Car *createSpecificCar(CarType type)
{
switch(type)
{
case BENZ: //生产奔驰
return (new BenzCar());
break;
case BMW: //生产宝马
return (new BmwCar());
break;
default:
return NULL;
break;
}
}
};
int main()
{
CarFactory carfac;
Car* specificCarA = carfac.createSpecificCar(BENZ);
Car* specificCarB = carfac.createSpecificCar(BMW);
//delete specificCarA; delete specificCarB;
return 0;
}
=============================运行结果==================================
BenzCar---奔驰
BmwCar---宝马