php设计模式(一)工厂模式

PHP设计模式(一)工厂模式

最近会简单的自我总结一些php当中的一些设计模式,当然个人才疏学浅,可能些不对的地方望各位看官见谅指正

是什么?

工厂模式是一种创建型的模式,简单的说就是用来创建对象的

为什么?

我们一般最普通的创建对象的方式是这样new classname(),但是换位想一下,这样创建对象的时候我们必须要知道类名,但是我们考虑一下下面几个情况:

  1. 如果我们不知道类名呢?
  2. 如果我在很多个文件当中都用到了这个类创建对象,new了很多次,但是在重构或者其他什么情况的时候我要修改类名怎么半?当然有人会说怎么会修改类名,这是有可能会遇到的,那说一一下常见一点的,如果我给这个类的构造方法加了,或者是少了一个参数?那岂不是得一个个的去改
  3. 我现在有一个抽象的基类,由它派生了很多子类,我不知道后面还会不会添加其他的子类

上面几个都是可能会遇到的一些情况之一,使用工厂模式可以比较好的解决上面的问题

怎么办?

简单工厂模式

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
class Food{
//todo
}

class FoodFactory{

static public function create(){
return new food();
}
}

$food= FoodFactory::create();

上面实现简单工厂模式,FoodFactory这个类很简单只有一个创建方法,返回food类的实例,当然也可以发现这个方法很笨拙,只能实现一个对象的创建,感觉比直接new一个对象
好不了多少,只是方便改动而已

工厂方法模式

1
2
3
4
5
6
7
8
9
10
11
12
class FoodFactory{

static public function create($classname){

if(include_once 'class/' . $classname . '.php'){
return new $classname;
} else {
throw new Exception('Driver not found');
}

}
}

通过上面的方法我们发现我们已经可以不局限于,创建一个固定的类的对象了
但是要注意的是:
如果我们使用了命名空间的话,在动态实例化类的时候必须包含完整的命名空间,提前use或者处于统一命名空间都是没有用的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
namespace Mohuishou\Lib;
class FoodFactory{
static public function create($classname){

if(include_once 'class/' . $classname . '.php'){
$classname="Mohuishou\Lib\\".$classname;
return new $classname;
} else {
throw new Exception('Driver not found');
}

}
}

如果我们还想传入参数呢?

1
2
3
4
5
6
7
8
9
10
11
12
<?php
namespace Mohuishou\Lib;
class FoodFactory{
static public function create($classname,$params){
if(include_once 'class/' . $classname . '.php'){
$classname="Mohuishou\Lib\\".$classname;
return new $classname($params);
} else {
throw new Exception('Driver not found');
}
}
}

如果我们不知道类名,不知道方法,怎么办?怎么实现一个一般的工厂模式?
这里可能需要用到反射的概念了,这篇就不过多赘述