工厂模式大致可以分为三类:
1、简单工厂模式
2、工厂方法模式
3、抽象工厂模式。
这三种模式逐步抽象,并且更具有一般性。
工厂模式有一种非常形象的描述,建立对象的类就像一个工厂,而需要被建立的对象就是一个个产品,在工厂中加工产品,使用产品的人不用关心产品是如何生产出来的。在软件中使用工厂模式的好处就是降低了模块之间的耦合。
一、简单工厂模式:
简单工厂模式是工厂模式中最简单的一种,他可以用比较简单的方式隐藏创建对象的细节,一般只需要告诉工厂类所需要的产品类型,工厂类就会返回需要的产品对象。
例:现在有一个工厂生产A,B两种类型的产品。使用工厂模式设计就是有一个工厂类Factory,可以根据输入的类型(typeA,typeB)从而创建相应的A类型对象,B类型对象。
#include<iostream>
using namespace std;
enum
{
typeA,
typeB,
};
class product
{
public:
virtual void show()=0;
};
class productA:public product
{
public:
virtual void show()
{
cout<<"product A"<<endl;
}
};
class productB:public product
{
public:
virtual void show()
{
cout<<"product B"<<endl;
}
};
class Factory
{
public:
static product* CreateProduct(int type)
{
switch(type)
{
case typeA:
return new productA();
break;
case typeB:
return new productB();
break;
}
}
};
int main()
{
Factory f;
product *a=f.CreateProduct(typeA);
product *b=f.CreateProduct(typeB);
a->show();
b->show();
return 0;
}
代码如上所示,可以看到使用简单工厂模式的话统一了创建对象的接口,隐藏了创建对象的细节,只要知道产品的类型就可以创建出产品对象。
但是简单工厂模式不易对产品进行扩展,比如现在又出来了一种C类型的产品,那要修改的地方就很多了,首先要添加一个C类型的产品类,还有在工厂类中再添加一个分支,这违背了开闭原则。
所以简单工厂模式适用于产品子类不多的场合。
二、工厂方法模式:
由于简单工厂模式违反了开闭原则,所以工厂方法模式的出现了,工厂方法模式是在简单工厂模式的基础上,对”工厂”添加了一个抽象层,将工厂的动作抽象出来,作为抽象类,而具体的行为由工厂类的子类去实现,让工厂类的子类决定去生产什么类型的产品。
例:现在有一个工厂生产A,B两种类型的产品。
#include<iostream>
using namespace std;
class product
{
public:
virtual void show()=0;
};
class productA:public product
{
public:
virtual void show()
{
cout<<"product A"<<endl;
}
};
class productB:public product
{
public:
virtual void show()
{
cout<<"product B"<<endl;
}
};
class Factory
{
public:
virtual product* CreateProduct()=0;
};
class FactoryA:public Factory
{
public:
virtual product* CreateProduct()
{
return new productA();
}
};
class FactoryB:public Factory
{
public:
virtual product* CreateProduct()
{
return new productB();
}
};
int main()
{
Factory* FA=new FactoryA();
product* a=FA->CreateProduct();
a->show();
Factory* FB=new FactoryB();
product* b=FB->CreateProduct();
b->show();
return 0;
}
相比较简单工厂模式而言,工厂方法模式遵循了开闭原则。工厂方法模式提供了一个抽象的工厂类接口,而具体的生产则是放到工厂类的子类当中,这样进一步抽象使得以后再增加新的产品的时候非常简单,不必修改原有代码,只需要增加一个新的工厂子类就可以了。
三、抽象工厂模式:
工厂方法模式和简单工厂模式都适用于”产品种类结构单一”的场合,为一类产品提供创建的接口。
例如生产牙膏的工厂只生产牙膏这一类产品,如果使用工厂方法模式的话,则这个工厂就不能同时生产牙刷。
如果想让生产牙膏的工厂同时生产牙刷的话,则可以使用抽象工厂模式。
抽象工厂模式使用与产品种类结构多的场合(比如A工厂里面既有高档牙膏也有高档牙刷),主要用于创建一组相关的产品,为他们提供创建的接口。
例:现在有两个工厂分别生产A,B组产品。A组里面包括高档牙膏和高档牙刷两类产品,B组里面包括低档牙膏和低档牙刷。
#include<iostream>
using namespace std;
class brush //牙刷抽象类
{
public:
virtual void* ToothBrush()=0;
};
class paste //牙膏抽象类
{
public:
virtual void* ToothPaste()=0;
};
class brush1:public brush
{
public:
void* ToothBrush()
{
cout<<"good toothbrush"<<endl;
}
};
class brush2:public brush
{
public:
void* ToothBrush()
{
cout<<"bad toothbrush"<<endl;
}
};
class paste1:public paste
{
public:
virtual void* ToothPaste()
{
cout<<"good toothpaste"<<endl;
}
};
class paste2:public paste
{
public:
virtual void* ToothPaste()
{
cout<<"bad toothpaste"<<endl;
}
};
class Factory
{
public:
virtual brush* CreateToothbrush()=0;
virtual paste* CreateToothpaste()=0;
};
class FactoryA:public Factory
{
public:
virtual brush* CreateToothbrush()
{
return new brush1();
}
virtual paste* CreateToothpaste()
{
return new paste1();
}
};
class FactoryB:public Factory
{
public:
virtual brush* CreateToothbrush()
{
return new brush2();
}
virtual paste* CreateToothpaste()
{
return new paste2();
}
};
int main()
{
Factory* FA=new FactoryA();
Factory* FB=new FactoryB();
brush *ba=FA->CreateToothbrush();
brush *bb=FB->CreateToothbrush();
ba->ToothBrush();
bb->ToothBrush();
paste* pa=FA->CreateToothpaste();
paste* pb=FB->CreateToothpaste();
pa->ToothPaste();
pb->ToothPaste();
return 0;
}
抽象工厂模式封装了产品的创建,只要我们知道工厂就可以创建出一组产品。但是缺点也很明显,比如新增一个产品,要在每个工厂中再添加一种方法,违反了开闭原则。