PHP 建造者模式

原文作者: xingguang
原文链接:https://www.tiance.club/post/1575233550.html

建造者模式和抽象工厂模式很像,总体上,建造者模式仅仅只比抽象工厂模式多了一个“导演类”的角色。与抽象工厂模式相比,建造者模式一般用来创建更为复杂的对象,因为对象的创建过程更为复杂,因此将对象的创建过程独立出来组成一个新的类 —— 导演类。也就是说,抽像工厂模式是将对象的全部创建过程封装在工厂类中,由工厂类向客户端提供最终的产品;而建造者模式中,建造者类一般只提供产品类中各个组件的建造,而将完整建造过程交付给导演类。由导演类负责将各个组件按照特定的规则组建为产品,然后将组建好的产品交付给客户端。

角色

指挥者角色(Director):构建一个使用Builder接口的对象
抽象建造者角色(Builder):为创建一个Product对象的各个部件指定的抽象接口
具体建造者角色(ConcreteBuilder):实现Builder接口,构造和装配各个部件
产品角色(Product)

1、基础抽象类(指挥者)

定义一个基础抽象类,规定所有实现者都必须实现规定的方法,比如想实现车辆的建造,首先必须规定好车辆有哪些零件,所有造车厂商都必须实现所有规定好的零件。

abstract class carModel
{

    //这里存储所有组装车需要的零件
    public $spareParts = array();

    //车的名字
    public $carName = "";

    //增加轮子部件
    public abstract function addLunzi($xinghao);

    //增加外壳部件
    public abstract function addWaike($xinghao);

    //增加发动机部件
    public abstract function addFadongji($xinghao);

    //获取车,并给车取名字
    final public function getCar($carName)
    {
        if ($this->spareParts) {
            $this->carName = $carName;
            //$k 代表部件名字
            //$v 代表型号
            foreach ($this->spareParts as $k => $v) {
                $actionName = "add" . $k;
                $this->$actionName($v);
            }
        } else {
            throw new Exception("没有汽车部件");

        }
    }
}

原文作者: xingguang
原文链接:https://www.tiance.club/post/1575233550.html

2、具体实现类(产品类)

即实现对应车辆根据对应的统一基础抽象类去统一实现,

//定义具体的产品
class bmwCarModel extends carModel
{

    public $spareParts = array();
    public $carName = "";

    public function addLunzi($xinghao)
    {
        echo "宝马" . $this->carName . "的轮子,型号是" . $xinghao . "
";
    }

    public function addWaike($xinghao)
    {
        echo "宝马" . $this->carName . "的外壳,型号是" . $xinghao . "
";
    }

    public function addFadongji($xinghao)
    {
        echo "宝马" . $this->carName . "的发动机,型号是 " . $xinghao . "
";
    }
}


//定义具体的产品
class benziCarModel extends carModel
{

    public $spareParts = array();
    public $carName = "";

    public function addLunzi($xinghao)
    {
        echo "奔驰" . $this->carName . "的轮子,型号是" . $xinghao . "
";
    }

    public function addWaike($xinghao)
    {
        echo "奔驰" . $this->carName . "的外壳,型号是" . $xinghao . "
";
    }

    public function addFadongji($xinghao)
    {
        echo "奔驰" . $this->carName . "的发动机,型号是 " . $xinghao . "
";
    }
}

3、抽象建造者

规范产品的组建,一般是由子类实现

//定义建造者
abstract class carBuilder
{
    public abstract function setSpareParts($partsName, $xinghao);
    public abstract function getCarModel($name);
}

4、具体建造者

实现抽象类定义的所有方法,并且返回一个组件好的对象。

class bmwBuilder extends carBuilder
{
    private $bmwModel;

    public function __construct()
    {
        $this->bmwModel = new bmwCarModel();
    }

    public function setSpareParts($partsName, $xinghao)
    {
        $this->bmwModel->spareParts[$partsName] = $xinghao;
    }

    public function getCarModel($name)
    {
        $this->bmwModel->getCar($name);
    }
}


class benziBuilder extends carBuilder
{
    private $benziModel;

    public function __construct()
    {
        $this->benziModel = new benziCarModel();
    }

    public function setSpareParts($partsName, $xinghao)
    {
        $this->bmwModel->spareParts[$partsName] = $xinghao;
    }

    public function getCarModel($name)
    {
        $this->bmwModel->getCar($name);
    }
}

具体调用代码:

    public function testObserver(){
        //模拟客户端调用

//创建一辆宝马车,取名字为宝马x1

        $bmwBuilder = new bmwBuilder();
        $bmwBuilder->setSpareParts('Lunzi', '牛逼轮子1号');
        $bmwBuilder->setSpareParts('Waike', '牛逼外壳1号');
        $bmwBuilder->setSpareParts('Fadongji', '牛逼发动机1号');
        $bmwBuilder->getCarModel("宝马x1");
        $bmwBuilder->getCarModel("宝马x1");  //连续创建两个宝马x1

//再创建一个宝马 没有外壳 取名为 宝马s5
        $bmwBuilder = new bmwBuilder();
        $bmwBuilder->setSpareParts('Lunzi', '牛逼轮子2号');
        $bmwBuilder->setSpareParts('Fadongji', '牛逼发动机2号');
        $bmwBuilder->getCarModel("宝马s5");
        $bmwBuilder->getCarModel("宝马s5");  //连续创建两个宝马x1

    }

总结

优点

1、客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。用户使用不同的具体建造者即可得到不同的产品对象,新增具体建造者符合“开闭原则”。
2、可以更精细地控制产品的创建过程。

缺点

1、不适用于内部变化复杂的产品。如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

总结

建造者模式,适用于创建有复杂内部结构的对象,对象属性之间相互依赖,且又可能要使用到一些其他不易得到的对象。

参考链接:https://www.cnblogs.com/mingmingcome/p/9637343.html

原文作者: xingguang
原文链接:https://www.tiance.club/post/1575233550.html

原文地址:https://www.cnblogs.com/yizhidaozuihou/p/12830117.html