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

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

是什么?

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

为什么?

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

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

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

怎么办?

简单工厂模式

<?php
	class Food{
	    //todo
	}

	class FoodFactory{

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

	$food= FoodFactory::create();

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

工厂方法模式

class FoodFactory{

	    static public function create($classname){

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

	    }
	}

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

<?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');
	        }

	    }
	}

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

<?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');
	}
    }
}

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