【PHP设计模式】工厂模式

139 阅读1分钟

【工厂模式】

      工厂模式,又称工厂方法模式。说到工厂,我们可以联想到一个服装厂可以生产出各式各样的衣服,随着市场的需要,也会生产出新的款式的衣服,但是我们并不能预测新款是什么样子,设计师设计出来交给工厂安排到对应生产线上生产就完了。

      在编程中与之相似的是,有时候我们在创建对象的过程中,并不能确定类一定创建(实例化)出哪一种类型的对象,我们更希望根据不同参数得到不同的类实例,这时我们可以通过定义一个父类作为定义创建对象的接口,将实例化推迟到子类中完成,让子类来决定实例化哪一个具体的对象。这样做的好处是把创建对象的过程封装了起来,通过一个工厂类来创建新的对象,而不是每创建一个对象就new一遍。

      结构:1个工厂父类(interface或abstract)   、多个具体工厂子类(实现父类接口或继承抽象父类)  

                 1个产品父类(interface或abstract)   、多个具体产品子类(实现父类接口或继承抽象父类)  

      示例:下面以一个服装厂生成衣服为例,服装厂有两个分厂,分别负责生产男装和女装

  • 抽象工厂父类 ClothesFactory.php :
<?php
namespace app\index\controller;
//抽象父类工厂(服装总厂)
abstract class ClothesFactory
{
    //要求子类(分厂)必须可以实现的方法(职能):
    //生产衣服
    abstract public function createClothes();
}
  •  具体工厂子类1 OneFactory.php:
<?php
namespace app\index\controller;
//具体工厂(第一分厂)继承父类工厂
class OneFactory extends ClothesFactory
{
    //实现父类定义的抽象方法(生产衣服的职能)
    public function createClothes()
    {
        //第一分厂负责生产男装
        return new ManClothes();
    }
}
  •   具体工厂子类2 TwoFactory.php:   
<?php
namespace app\index\controller;
//具体工厂(第二分厂)继承父类工厂
class TwoFactory extends ClothesFactory
{
    //实现父类定义的抽象方法(生产衣服的职能)
    public function createClothes()
    {
        //第二分厂负责生产女装
        return new WomanClothes();
    }
}
  • 抽象产品父类 Clothes.php:
<?php
namespace app\index\controller;
//抽象产品父类(所有种类衣服)
abstract class Clothes
{
    //定义数量、尺码属性
    protected $num;
    protected $size;

    public function __set($name,$value){
        $this->$name = $value;
    }

    public function __get($name){
        return $this->$name;
    }

    //要求子类(子产品 男装女装等)必须可以被执行的方法(操作):
    //被生产
    abstract public function create();
}
  • 具体产品子类1 ManClothes.php :
<?php
namespace app\index\controller;
//子类产品(男装)
class ManClothes extends Clothes
{
    //被生产
    public function create()
    {
        return '男装数量:'. $this->num . ',尺码:' . $this->size;
    }
}
  • 具体产品子类2 WomanClothes.php :
<?php
namespace app\index\controller;
//子类产品(女装)
class WomanClothes extends Clothes
{
    //被生产
    public function create()
    {
        return '女装数量:'. $this->num . ',尺码:' . $this->size;
    }
}
  • 测试:
<?php
namespace app\index\controller;
class Test
{
    public function test()
    {
        $factory = new OneFactory();
        $toDo = $factory->createClothes();
        $toDo->num = 1;
        $toDo->size = 'xxl';
        $res = $toDo->create();
        var_dump($res);
    }
}