情景:
从前,有一家叫做骚尼大法(简称大法)的公司,有富土康一个生产企业。富土康开了两条生产线,手机生产线跟电视生产线。大法跟富土康这两个好基友一直相处得很好,直到某一天来了个大米。
大米跟大法有样学样生产其手机来,那么现在富土康的手机生产线跟电视生产线就生产大米跟大法的产品了。我们看图。
UML类图
大米(DaMi)跟大法(DaFa)是两个抽象产品,而大米手机(DaMi_Phone)大米电视(DaMi_TV),大法手机(DaFA_Phone)大法电视(DaFA_TV)是对像个抽象产品的具体分类实现。富土康(Futukang)是抽象工厂接口,它里面包含所有产品创建的抽象方法。Futukang_Phone,Futukang_TV就是具体的工厂。
通常是运行时创建一个具体工厂(ConcreteFactory),这个具体工厂再创建特定实现的产品对象(ConcreteProduct)。为创建不同的产品对象,客户端对应不同的具体工厂。
#include <iostream>
using namespace std;
class DaFa
{
public:
virtual void Show() = 0;
};
class DaFa_Phone : public DaFa
{
public:
void Show()
{
cout<< "I'm DaFa_Phone"<<endl;
}
};
class DaFa_TV : public DaFa
{
public:
void Show()
{
cout<< "I'm DaFa_TV"<<endl;
}
};
class DaMi
{
public:
virtual void Show() = 0;
};
class DaMi_Phone : public DaMi
{
public:
void Show()
{
cout<< "I'm DaMi_Phone"<<endl;
}
};
class DaMi_TV : public DaMi
{
public:
void Show()
{
cout<< "I'm DaMi_TV"<<endl;
}
};
class Futukang
{
public:
virtual DaMi *CreateDaMi() = 0;
virtual DaFa *CreateDaFa() = 0;
};
class Futukang_Phone : public Futukang
{
public:
DaMi *CreateDaMi()
{
return new DaMi_Phone ();
}
DaFa *CreateDaFa()
{
return new DaFa_Phone ();
}
};
class Futukang_TV : public Futukang
{
public:
DaMi *CreateDaMi()
{
return new DaMi_TV ();
}
DaFa *CreateDaFa()
{
return new DaFa_TV ();
}
};
int main(int argc , char *argv [])
{
Futukang *factory_phone = new Futukang_Phone ();
DaMi *dami_phone = factory_phone->CreateDaMi();
DaFa *dafa_phone = factory_phone->CreateDaFa();
dami_phone->Show();
dafa_phone->Show();
Futukang *factory_tv = new Futukang_TV ();
DaMi *dami_tv = factory_tv->CreateDaMi();
DaFa *dafa_tv = factory_tv->CreateDaFa();
dami_tv->Show();
dafa_tv->Show();
if (factory_phone != NULL)
{
delete factory_phone;
factory_phone = NULL;
}
if (factory_tv != NULL)
{
delete factory_tv;
factory_tv = NULL;
}
if (dami_phone != NULL)
{
delete dami_phone;
dami_phone = NULL;
}
if (dafa_phone != NULL)
{
delete dafa_phone;
dafa_phone = NULL;
}
if (dami_tv != NULL)
{
delete dami_tv;
dami_tv = NULL;
}
if (dafa_tv != NULL)
{
delete dafa_tv;
dafa_tv = NULL;
}
return 0;
}
优点:
l 跟工厂方法模式相比,少创建了对象。容易维护管理。
l 让具体的创建实例的过程与客户端分离,产品的具体类名也被具体工厂的实现分离。
l 适用于产品种类结构多的场合,主要用于创建一组(有多个种类)相关的产品,为它们提供创建的接口
缺点:
l 新增一个Product的时候将会变得异常麻烦
情景2:
大米跟大法在富士康相处得很好,可是某一天来了个诺基鸭。除了要增加个诺基鸭,诺基鸭手机,诺基鸭电视三个类之外。还要弄个诺基鸭砖头。还要把富土康,富土康手机,富土康电视都修改一遍。太麻烦了,大米跟大法两个不干了,决定重新修改。
#include <iostream>
using namespace std;
class DaFa
{
public:
virtual void Show() = 0;
};
class DaFa_Phone : public DaFa
{
public:
void Show()
{
cout<< "I'm DaFa_Phone"<<endl;
}
};
class DaFa_TV : public DaFa
{
public:
void Show()
{
cout<< "I'm DaFa_TV"<<endl;
}
};
class DaMi
{
public:
virtual void Show() = 0;
};
class DaMi_Phone : public DaMi
{
public:
void Show()
{
cout<< "I'm DaMi_Phone"<<endl;
}
};
class DaMi_TV : public DaMi
{
public:
void Show()
{
cout<< "I'm DaMi_TV"<<endl;
}
};
class Nuojiya
{
public:
virtual void Show() = 0;
};
class Nuojiya_Phone : public Nuojiya
{
public:
void Show()
{
cout<< "I'm Nuojiya_Phone"<<endl;
}
};
class Nuojiya_TV : public Nuojiya
{
public:
void Show()
{
cout<< "I'm Nuojiya_TV"<<endl;
}
};
class Nuojiya_Brick:public Nuojiya
{
public:
void Show()
{
cout<< "I'm Nuojiya_Brick"<<endl;
}
};
class Futukang
{
private:
char item;
public:
Futukang(char _item){item=_item;}
DaFa* CreateDaFa(){
DaFa* result=NULL;
switch(item){
case 'P':
result=new DaFa_Phone;
break;
case 'T':
result=new DaFa_TV;
break;
}
return result;
}
DaMi* CreateDaMi(){
DaMi* result=NULL;
switch(item){
case 'P':
result=new DaMi_Phone;
break;
case 'T':
result=new DaMi_TV;
break;
}
return result;
}
Nuojiya* CreateNuojiya(){
Nuojiya* result=NULL;
switch(item){
case 'P':
result=new Nuojiya_Phone;
break;
case 'T':
result=new Nuojiya_TV;
break;
case'B':
result=new Nuojiya_Brick;
break;
}
return result;
}
};
int main(int argc , char *argv [])
{
Futukang phone=Futukang('P');
Futukang tv=Futukang('T');
Futukang brick=Futukang('B');
DaFa* dafa_phone=phone.CreateDaFa();
DaFa* dafa_tv=tv.CreateDaFa();
DaMi* dami_phone=phone.CreateDaMi();
DaMi* dami_tv=tv.CreateDaMi();
Nuojiya* nuojiya_phone=phone.CreateNuojiya();
Nuojiya* nuojiya_tv=tv.CreateNuojiya();
Nuojiya* nuojiya_brick=brick.CreateNuojiya();
dafa_phone->Show();
dafa_tv->Show();
dami_phone->Show();
dami_tv->Show();
nuojiya_phone->Show();
nuojiya_tv->Show();
nuojiya_brick->Show();
return 0;
}
去除Futukang_TV,Futukang_Phone,Futukang。取而代之的是Futukang这一个类,用一个简单工厂模式来实现。当然,在这以后,无论外界发生什么事情都不关大米跟大法两家的事了,就算新增一个“蓝翔”,富土康再新增一条“挖掘机”的流水线,都不关他们的事了。只需要在Futukang新增一个方法,然后再客户端作相应的修改就行。达到了解耦的目的。