1.作用
在你创建自定义对象的地方都可以使用该模式。核心作用:将创建对象者和创建的对象解耦了,创建着甚至不知道创建的真实对象是什么,仅仅知道一个代号。
意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实例实例化延迟到子类
核心:在子类中创建对象,客户仅知晓接口。
2.UML类图
参与者:
- Product:产品抽象类,定义产品的接口。
- ConcreteProduct:产品,实现产品接口。
- Factory:工厂抽象类,主要定义创建产品的接口,即工厂方法,返回产品对象。
- ConcreteFactory:工厂具体类,实现产品的创建,通常传入参数是产品的代号,即枚举或者字符串标记
3.实现
举例:既然是工厂模式,这里就举一个工厂的例子,小明最近开了一家工厂名字叫——小明工厂,可以生产电视机,冰箱,洗衣机,刚开始品种不能太多,也不能太少。
类图
- 代码
#include <iostream>
using namespace std;
/****************产品****************************/
typedef enum//代号枚举
{
TV_Enum,
Fridge_Enum,
Washer_Enum
}ProductEnum;
//产品抽象类
class Product
{
public:
Product(){}
virtual ~Product(){}
virtual void showMe() = 0;
};
/***电视机***/
class Tv: public Product
{
public:
Tv(){}
~Tv(){}
virtual void showMe()
{
cout << "我是一台电视机!" << endl;
}
};
/***冰箱***/
class Fridge: public Product
{
public:
Fridge(){}
~Fridge(){}
virtual void showMe()
{
cout << "我是一台冰箱!" << endl;
}
};
/***洗衣机***/
class Washer :public Product
{
public:
Washer(){}
~Washer(){}
virtual void showMe()
{
cout << "我是一台洗衣机!" << endl;
}
};
/****************************工厂***************************/
/**工厂抽象类,一般工厂必须具备的功能**/
class Factory
{
public:
Factory(){}
virtual ~Factory(){}
//核心接口
virtual Product* createProduct(ProductEnum productName) = 0;
};
class XiaoMFactory :public Factory
{
public:
XiaoMFactory(){}
virtual ~XiaoMFactory(){}
//核心接口
virtual Product* createProduct(ProductEnum productName);
};
/**小明的工厂**/
Product* XiaoMFactory::createProduct(ProductEnum productName)
{
Product *p;
switch (productName)
{
case TV_Enum:
p = new Tv;
break;
case Fridge_Enum:
p = new Fridge;
break;
case Washer_Enum:
p = new Washer;
break;
default:break;
}
return p;
}
/***********工厂开始运行*********************/
int main()
{
Factory *factory = new XiaoMFactory;
//开始造产品
Product * tv = factory->createProduct(TV_Enum);
tv->showMe();
Product * washer = factory->createProduct(Washer_Enum);
washer->showMe();
Product * fridge = factory->createProduct(Fridge_Enum);
fridge->showMe();
delete factory;
delete tv;
delete washer;
delete fridge;
return 0;
}
- 结果
我是一台电视机!
我是一台洗衣机!
我是一台冰箱!
请按任意键继续…
4.优缺点
优点:
- 对象的创建完全被隐藏了,我传入代号就可以生产产品了,实现了创建者和被创建对象的解耦。
- 扩展方便,如果需要增加一个产品,工厂方法中添加一个分支即可,貌似JAVA都可以使用传入类名来识别所需创建的实例,那样工厂方法就完全无需改动。
缺点:
- 原来一句话搞定的事,凭空多了一个类,对于产品类较少,或者变化不大时确实有点多余,增加了多余的代码。
5.适用场景
- 在你不确定将来是否还要增加新的产品对象时请使用;
- 在你的程序中有许多同一层次的对象需要创建时,特别是他们可以在你的程序中可以相互替代的时候(结合策略模式);
6. 总结
或许有人发现了工厂类图中抽象类是多余的,确实在本例中他是多余的,抽象类的存在是为了工厂模式的变种,如简单工长,多工厂等。接下来在继续学习介绍。