1、什么是工厂模式:
工厂模式就是为类实例的创建提供过渡接口,将复杂的对象创建过程封装、屏蔽起来,达到提高灵活性的目的。可以看下面一个简单的例子:如果我们有大众和通用两种品牌的车,都派生于一个基类“car”,两种车有各自的一些特性(类成员),那么在创建他们时就要做不同的初始化工作,为了方便的生产这两种车,建立了一个工厂,该工厂可以根据客户提供的品牌代码与车型代码去生产这些车辆(factory的create方法)。。。
//------------------------------------------------
// a simple example of factory paradigm
// base class: car
// Derived Class: dasAutoCar & GMCar
// factory class: carFactory
//------------------------------------------------
#include
#include
using namespace std;
// -- base class
class car
{
public: //
car(string str):brandName(str){};
virtual ~car(){}; // 汽车类,基类,将析构函数定义为虚函数
string getBrandName(){return brandName;};
private:
string brandName;
};
// drive class
class dasAutoCar: public car
{
//…… 细节并不重要
int code;
public:
dasAutoCar(int carCode):car(string("dasAuto")),code(carCode){};
};
// drive class
class GMCar: public car
{
int code;
public:
GMCar():car(string("dasAuto")){};
};
// factory class
class carFactory
{
public:
car* create(int brandCode, int carCode=0) // 构造函数的参数为品牌代码
{
switch(brandCode)
{
case 1: // 如果品牌代码为1, 生产一辆大众车
return new dasAutoCar(carCode);
break;
case 2: // 如果品牌代码为2,生产一辆通用车
return new GMCar();
break;
default:
return 0;
}
}
};
// main function: test above code
void main()
{
carFactory cf;
car* myCar = cf.create(1,001); //生产了一辆大众车
cout<getBrandName()<//注意,这里没有delete会内存泄漏啊
}
上例实际上是工场模式的第一种形式:简单工厂模式。
工厂模式有根据其抽象层次与实现方法的不同分为:
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
2、为什么要用工厂模式:
工厂模式的最大目的就是希望降低耦合,客户只需要告知工厂,需要什么样的产品,而不需要知道产品的具体实现过程。
另外,effective c++告诉我们,在使用工厂模式的情况下,可以直接使用智能指针来管理产生的产品,避免造成内存泄漏:
3、工厂模式的三种实现方式及其各自的优劣:
ok,感觉自己有点学的不深刻,还是继续以“汽车”为例,写一下工程模式的三种实现吧:
第一: 简单工厂模式
#define _CRTDBG_MAP_ALLOC
#include
#include // 和内存泄漏检测相关的头文件
#include
#include // 引入智能指针的头文件,VS2010环境
using namespace std;
// base class: car
class car
{
public:
string brand; //汽车的品牌
car(string brd):brand(brd){};
virtual ~car(){}; //注意,将基类的析构函数定义为虚函数
};
class BwmCar: public car
{
public:
BwmCar(string brd,int codes): car(brd),code(codes){cout<<"a BWM car was build!"<private:
/* 一些宝马车的特殊参数*/
int code;
};
class BenzCar: public car
{
public:
BenzCar(string brd, int codes): car(brd),code(codes)
{
cout<<"a benz car was build!"<private:
/* 一些奔驰车的特殊参数 */
int code;
};
class factory
{
public:
car* createCar(int brandNum)
{
switch(brandNum)
{
case 1:
return new BwmCar("BWM",0);
break;
case 2:
return new BenzCar("Benz", 0);
break;
default:
return 0; //return a NULL pointer
break;
}
}
};
int main()
{
factory f;
{
shared_ptr pCar(f.createCar(1));
//car* pCar = f.createCar(2);
}
_CrtDumpMemoryLeaks();
return 0;
}
上述就是第一类(简单工厂模式的典型实现),将一些产品的实现过程封装在一个工程类中,将产品的实现过程隐藏起来,而用户只需要将能标志产品类别的参数传递给工厂中的create方法就可以获得所需的产品。
这样做有什么好处呢?封装复杂的产品实现过程!案例中产品的生产过程很简单,直接new就好了,但是实际上,有时候一个产品的构造函数可能需要很多的参数,而这些参数可能需要通过一系列的计算才能得到,在多线程的程序中还可能涉及到一些同步问题,如果把这些程序段都放在主程序中会使得代码过于臃肿。
第二:工厂方法模式
对于简单工厂模式,一个工厂会生产各种各样的产品,每增加一个新的产品都需要重新修改工产类,对用户而言,很麻烦,不是吗?如果你也这样认为,请使用工厂方法模式:
class factory
{
public:
virtual car* createCar(int brandNum) =0; //pure virtual
};
class BwmFac: public factory
{
public:
virtual car* createCar(){return new BwmCar("BWM",0);}
};
class BenzFac: public factory
{
public:
virtual car* createCar(){return new BenzCar("Benz",0);}
};
这样一个工厂就生产一种产品了,希望生产出哪种产品就先建立一个对应的工厂,并通过工厂去产生产品!!!
如果客户需要多一种产品,也无需修改原有的工厂类,再建一个新的就是咯!!!
当然,如果产品很多呢?例如,宝马有很多型号的车啊,当然,奔驰也有,一个车型一个工厂是不是好浪费,那请使用抽象工厂模式。。。
第三:抽象工厂模式:
/*
** FileName : AbstractFactoryPatternDemo
** Author : Jelly Young
** Date : 2013/11/19
** Description : More information
*/
#include
using namespace std;
// Product A
class ProductA
{
public:
virtual void Show() = 0;
};
class ProductA1 : public ProductA
{
public:
void Show()
{
cout<<"I'm ProductA1"<public ProductA
{
public:
void Show()
{
cout<<"I'm ProductA2"<// Product B
class ProductB
{
public:
virtual void Show() = 0;
};
class ProductB1 : public ProductB
{
public:
void Show()
{
cout<<"I'm ProductB1"<public ProductB
{
public:
void Show()
{
cout<<"I'm ProductB2"<// Factory
class Factory
{
public:
virtual ProductA *CreateProductA() = 0;
virtual ProductB *CreateProductB() = 0;
};
class Factory1 : public Factory
{
public:
ProductA *CreateProductA()
{
return new ProductA1();
}
ProductB *CreateProductB()
{
return new ProductB1();
}
};
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;
}
}
======================================================
未完,待续。
2016.10.26