实际上本来是要写迭代器的,不过在看了一篇工厂模式的文章之后,觉得自己对工厂模式了解的不够全面。
简单复述一下工厂模式的类型和扩展。
工厂模式可分为简单工厂、工厂方法和抽象工厂模式。
工厂方法模式(Factory Method Pattern)又叫虚拟构造函数(Virtual Constructor)模式或者多态性工厂(Polymorphic Factory)模式。工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际创建性工作推迟到子类中。
■ 简单工厂模式中,一个工厂类处于对产品类实例化的中心位置上,它知道每一个产品,它决定哪一个产品类应当被实例化。这个模式的优点是允许客户端相对独立于产品创建的过程,并且在系统引入新产品的时候无须修改客户端,即在某种程度上支持“开-闭”原则。这个模式的缺点是对“开-闭”原则的支持不够,因为如果有新的产品加入到系统中,则需要修改工厂类,将必要的逻辑加入到工厂类中。
■ 工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,且克服了它的缺点。首先,在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建的工作交给子类去做。这个核心类则成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪个产品类应当被实例化的细节。此种进一步抽象化的结果,使这种工厂方法模式可以用来允许系统在不修改具体工厂角色的情况下引进新的产品,这一特点使得工厂模式具有超过简单工厂的优越性。
■ 抽象工厂模式是所有形态的工厂模式中最为抽象和最具有一般性的一种形态。抽象工厂模式与工厂方法模式的最大区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂则需要面对多个产品等级结构。
简单工厂模式
也叫静态工厂模式,就是有一个工厂,根据不同订单生产不同的产品。
#include <iostream>
using namespace std;
typedef enum phonetype {
TYPE_XIAOMI,
TYPE_APPLE,
}phoneType;
class Phone
{
public:
virtual void call() = 0;
};
class MiPhone:public Phone
{
public:
virtual void call()
{
cout<<"我在用小米手机打电话..."<<endl;
}
};
class iPhone:public Phone
{
public:
virtual void call()
{
cout<<"我在用苹果手机打电话..."<<endl;
}
};
class Factory
{
public:
Phone* creatPhone(int phoneType)
{
Phone* phone = NULL;
switch(phoneType)
{
case TYPE_XIAOMI:
phone = new MiPhone;
break;
case TYPE_APPLE:
phone = new iPhone;
break;
default:
phone = new iPhone;
break;
}
return phone;
}
};
int main()
{
Factory Foxcon;
Phone* phone = Foxconn.creatPhone(TYPE_APPLE);
phone->call();
return 0;
}
工厂方法模式
工厂方法模式下,就是有不同的工厂来生产,而不是一个固定的工厂。除了富士康,还有伟创力。
因此,我们有必要把工厂泛化:
class Factory
{
public:
virtual Phone* creatPhone(int phoneType) = 0;
};
class Foxconn :public Factory
{
public:
virtual Phone* creatPhone(int phoneType)
{
cout<<"富士康正在生产手机..."<<endl;
Phone* phone = NULL;
switch(phoneType)
{
case TYPE_XIAOMI:
phone = new MiPhone;
break;
case TYPE_APPLE:
phone = new iPhone;
break;
default:
phone = new iPhone;
break;
}
return phone;
}
};
class Flex :public Factory
{
public:
virtual Phone* creatPhone(int phoneType)
{
cout<<"伟创力正在生产手机..."<<endl;
Phone* phone = NULL;
switch(phoneType)
{
case TYPE_XIAOMI:
phone = new MiPhone;
break;
case TYPE_APPLE:
phone = new iPhone;
break;
default:
phone = new iPhone;
break;
}
return phone;
}
};
此时,在产量不足的情况下,我们可以安排多家工厂生产了:
int main()
{
Factory* foxcon = new Foxconn ;
Phone* phone1 = foxcon->creatPhone(TYPE_APPLE);
phone1->call();
Factory* flex = new Flex ;
Phone* phone2 = flex->creatPhone(TYPE_APPLE);
phone2->call();
return 0;
}
抽象工厂模式
抽象工厂模式是对工厂方法模式的扩展,就是添加更多的商品类型。在上面的例子中,我们只生产手机。然而,电脑、电纸书等其他商品也是可以生产的。我们看到一下几点:
- 简单工厂模式:我们可以生产某一类型的产品
- 工厂方法模式:我们可以分派不同工厂来生产
- 抽象工厂模式:我们可以生产不同类型的产品
要生产电脑,我们需要能够下达生产电脑的接口。因此需要增加电脑产品:
typedef enum PC_type {
TYPE_LENOVO,
TYPE_HP,
}PCType;
class PC
{
public:
virtual void qq() = 0;
};
class LenovoPC:public PC
{
public:
virtual void qq()
{
cout<<"我在用联想电脑登陆qq..."<<endl;
}
};
class HPPC:public PC
{
public:
virtual void qq()
{
cout<<"我在用惠普电脑登陆qq..."<<endl;
}
};
同时,需要能够给工厂下达生产电脑的方法:
class Factory
{
public:
virtual Phone* creatPhone(int phoneType) = 0;
virtual PC* creatPC(int PCType) = 0;
};
class Foxconn :public Factory
{
public:
virtual Phone* creatPhone(int phoneType)
{
cout<<"富士康正在生产手机..."<<endl;
Phone* phone = NULL;
switch(phoneType)
{
case TYPE_XIAOMI:
phone = new MiPhone;
break;
case TYPE_APPLE:
phone = new iPhone;
break;
default:
phone = new iPhone;
break;
}
return phone;
}
virtual PC* creatPC(int pcType)
{
cout<<"富士康正在生产电脑..."<<endl;
PC* pc = NULL;
switch(pcType)
{
case TYPE_LENOVO:
pc = new LenovoPC;
break;
case TYPE_HP:
pc = new HPPC;
break;
default:
pc = new HPPC;
break;
}
return pc;
}
};
class Flex :public Factory
{
public:
virtual Phone* creatPhone(int phoneType)
{
cout<<"伟创力正在生产手机..."<<endl;
Phone* phone = NULL;
switch(phoneType)
{
case TYPE_XIAOMI:
phone = new MiPhone;
break;
case TYPE_APPLE:
phone = new iPhone;
break;
default:
phone = new iPhone;
break;
}
return phone;
}
virtual PC* creatPC(int pcType)
{
cout<<"伟创力正在生产电脑..."<<endl;
PC* pc = NULL;
switch(pcType)
{
case TYPE_LENOVO:
pc = new LenovoPC;
break;
case TYPE_HP:
pc = new HPPC;
break;
default:
pc = new HPPC;
break;
}
return pc;
}
};
然后我们可以管理不同的工厂和产品了:
int main()
{
Factory* foxcon = new Foxconn ;
Phone* my_iPhone = foxcon->creatPhone(TYPE_APPLE);
my_iPhone->call();
PC* ideaPad = foxcon->creatPC(TYPE_LENOVO);
ideaPad->qq();
Factory* flex = new Flex ;
Phone* my_miPhone = flex->creatPhone(TYPE_XIAOMI);
my_miPhone->call();
PC* hp = flex->creatPC(TYPE_HP);
hp->qq();
return 0;
}
输出:
富士康正在生产手机…
我在用苹果手机打电话…
富士康正在生产电脑…
我在用联想电脑登陆qq…
伟创力正在生产手机…
我在用小米手机打电话…
伟创力正在生产电脑…
我在用惠普电脑登陆qq…