工厂模式通俗来说是指,为一些有着相同结构的类创建一个类族,并且为这个族群提供唯一一个入口类。请注意“相同结构”这个描述,它指的是某类物体拥有一些能让我们区别与其他物体的特征,比如说现在有一道联想题,通过两个词联想一样东西。“四个轮子,烧汽油”。我想你肯定能立刻就联想到小轿车、面包车、的士之类的汽车,不会联想到摩托车。这里的“四个轮子”和“烧汽油”便是小轿车、面包车、的士的相同特征,我们以它们来将小轿车、面包车和的士归类为“汽车”这个族群。
回到php当中,这里将以实例来说明工厂模式。
现在有一个汽车工厂,它生产小汽车和巴士车,小汽车和巴士车都是由引擎、车身和轮子组成的。
分析:
1、生产各种汽车有共同的标准,都必须生产引擎、车身和轮子,于是我们可以为生产汽车制定一个接口类,各类汽车都必须遵循这个接口类中的标准。
2、外界需要从工厂提供生产小汽车和巴士车的入口。
//生产汽车的标准
interface carNorms{
function engine();//引擎
function body();//车身
function whell();//轮子
}
//生产小汽车
class car implements carNorms{
public function engine(){
return '汽车引擎';
}
public function body(){
return '汽车车身';
}
public function whell(){
return '汽车轮子';
}
}
//生产巴士车
class bus implements carNorms{
public function engine(){
return '巴士引擎';
}
public function body(){
return '巴士车身';
}
public function whell(){
return '巴士轮子';
}
}
//汽车工厂
class carFactory{
static public function carInstance($type){
$instance='';
switch($type){
case 'car':
$instance=new car();
break;
case 'bus':
$instance=new bus();
break;
default:
throw new Exception('本工厂无法生产这种类型的车');
}
if(!$instance instanceof carNorms){
throw new Exception('这种车不符合生产标准');
}
return $instance;
}
}
$createCar=carFactory::carInstance('car');
$car['engine']=$createCar->engine();
$car['body']=$createCar->body();
$car['whell']=$createCar->whell();
print_r($car);
这是一个标准的工厂类,现在新的需求来了,工厂还需要生产卡车。
分析:由于生产卡车也符合该工厂的生产标准,我们可以直接加入卡车类,并在工厂类中增加相应的入口。
class truck implements carNorms{
public function engine(){
return '卡车引擎';
}
public function body(){
return '卡车车身';
}
public function whell(){
return '卡车轮子';
}
}
//汽车工厂
class carFactory{
static public function carInstance($type){
$instance='';
switch($type){
case 'car':
$instance=new car();
break;
case 'bus':
$instance=new bus();
break;
case 'truck':
$instance=new truck();
break;
default:
throw new Exception('本工厂无法生产这种类型的车');
}
if(!$instance instanceof carNorms){
throw new Exception('这种车不符合生产标准');
}
return $instance;
}
}
很轻松的完成了,但是我们在这假设一下,如果生产标准变了,生产环节还需要加入质量检测,我们要完成这个更改,必须在接口中加入质量测试方法。
//生产汽车的标准
interface carNorms{
function engine();//引擎
function body();//车身
function whell();//轮子
function check();//质量测试
}
麻烦的是,工厂生产的所有汽车都必须加入质量检测方法,在该工厂中,只生产三种汽车,似乎不是很麻烦。但我们再想一想,若是一个工厂有成千上万种产品,增加一个标准将要给每一种产品都添加进这种标准,将产生多么大的成本开销!这就是工厂方法的不足之处,使用工厂模式一定要注意!