首页 » 莫回首 » PHP设计模式(一)工厂模式

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

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

        }
    }

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