PHP设计模式(五)之建造者模式

作者: 温新

分类: 【设计模式】

阅读: 2144

时间: 2019-12-24 16:53:01

一、什么是建造者模式

**定义:**建造者模式(Builder Pattern)又称生成器模式,是一种构建对象的模式。

1)它可以将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象。

2)由于建造零件的过程很复杂,因此,这些零件的建造过程往往被“外部化”到另一个乘坐建造者的对象里,建造者对象返还给客户端的是一个全部零件都建造完毕的产品对象。它将产品的结构和建造过程对客户端隐藏起来。

【释义】

使用生活中的例子来接近建造者模式

1)去餐馆吃饭,点个辣子鸡,A店可能辣一点,B店可能淡一点,每一家店都有自己的做法,因此也就有不同的味道,所以就有了好吃与否的问题。

2)快餐店,KFC,德克士...无论在哪个城市的哪家店,它们的味道与做法都是一样的,用户只需要下订单就能吃到了。

二、建造者模式的四种角色

Builder:抽象构造者类,为创建一个Product对象的各个部件指定抽象接口。

ConcreteBuilder:具体构造者类,实现Builder的接口以构造和装配该产品的各个部件。定义并明确它所创建的表示。提供一个检索产品的接口

**Director:指挥者,**构造一个使用Builder接口的对象。

**Product:表示被构造的复杂对象。**ConcreateBuilder创建该产品的内部表示并定义它的装配过程。

三、建造者模式的使用场景

使用场景:一些基本的部件不会改变,而其它组合经常发生变化的时候。

四、建造者模式优缺点

优点

1)每个具体构建者相互独立,利于系统扩展;

2)客户端不必知道产品内部细节,利于细节风险控制;

3)建造者模式比较独立,将对象本身与构建过程解耦

4)精准控制构建出的对象和内容,构造层和显示层是分离的

缺点

1)产品的组成部分必须相同,这限制了其使用范围。

2)如果产品的内部变化复杂,该模式会增加很多的建造者类。

五、建造者模式与工厂模式的区别

1)与抽象工厂模式相比,建造者模式返回一个组装好的完整产品,而抽象工厂模式返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族 。

2)在抽象工厂模式中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象,而在建造者模式中,客户端可以不直接调用建造者的相关方法,而是通过指挥者类来指导如何生成对象,包括对象的组装过程和建造步骤,它侧重于一步步构造一个复杂对象,返回一个完整的对象 。

3)如果将抽象工厂模式看成汽车配件生产工厂,生产一个产品族的产品,那么建造者模式就是一个汽车组装工厂,通过对部件的组装可以返回一辆完整的汽车

总结:建造者模式更关注于零件装配的顺序

六、代码实现

AbstractBuilder.php

<?php
/**
 * 抽象豆腐构造者类 =>  对应Builder
 */

abstract class AbstractBuilder
{
    // 存储具体产品实例对象
    protected $toFu;

    public abstract function buildStep1();
    public abstract function buildStep2();
    public abstract function buildStep3();

    public abstract function getToFu();
}

ToFu.php

<?php

/**
 * 具体实体,豆腐产品角色  =>  对应Product
 */
class ToFu
{
    // 做豆腐的三个步骤
    protected $step1;
    protected $step2;
    protected $step3;

    public function setStep1($str)
    {
        $this->step1 = $str;
    }

    public function setStep2($str)
    {
        $this->step2 = $str;
    }

    public function setStep3($str)
    {
        $this->step3 = $str;
    }

    public function showToFu()
    {
        echo '新鲜美味的豆腐有三个步骤:' . $this->step1 . $this->step2 . $this->step3;
    }

}

CreateBuilderToFu.php // 新鲜豆腐构造者

<?php

/**
 * 具体豆腐产品角色构造者类     =》  对应 ConcreteBuilder
 */

class CreateBuilderToFu extends AbstractBuilder
{
    public function __construct()
    {
        // 实例化具体产品
        $this->toFu = new ToFu();
    }

    // 制作豆腐的第一步
    public function buildStep1()
    {
        $this->toFu->setStep1('第一步');
    }

    // 制作豆腐的第二步
    public function buildStep2()
    {
        $this->toFu->setStep2('第二步');
    }

    // 制作豆腐的第三步
    public function buildStep3()
    {
        $this->toFu->setStep3('第三步');
    }

    // 新鲜的豆腐
    public function getToFu()
    {
        return $this->toFu;
    }

}

CreateBuilderMaPoToFu.php // 麻婆豆腐构造者

<?php

/**
 * 具体豆腐产品角色构造者类     =》  对应 ConcreteBuilder
 */

class CreateBuilderMaPoToFu extends AbstractBuilder
{
    public function __construct()
    {
        $this->toFu = new ToFu();
    }

    // 制作豆腐的第一步
    public function buildStep1()
    {
        $this->toFu->setStep1('麻婆豆腐的做法:第一步,准备豆腐,切小块,并准备配料~~~~');
    }

    // 制作豆腐的第二步
    public function buildStep2()
    {
        $this->toFu->setStep2('麻婆豆腐的做法:第二步,入锅翻炒~~~');
    }

    // 制作豆腐的第三步
    public function buildStep3()
    {
        $this->toFu->setStep3('麻婆豆腐的做法:第三步,客观,你的四川麻婆豆腐做好了~~~');
    }

    // 获取麻婆豆腐
    public function getToFu()
    {
        return $this->toFu;
    }

}

Director.php

<?php

/**
 * 产品指挥者    =》  对应  Director
 */
class Director
{
    public $build;

    public function setBuilder(AbstractBuilder $builder)
    {
        $this->build = $builder;
    }

    public function startBuild()
    {
        $this->build->buildStep1();
        $this->build->buildStep2();
        $this->build->buildStep3();

        return $this->build->getToFu();
    }
}

index.php

<?php
require_once './AbstractBuilder.php';
require_once './CreateBuilderToFu.php';
require_once './CreateBuilderMaPoToFu.php';
require_once './ToFu.php';
require_once './Director.php';

// 实例化指挥着
$director    = new Director();

// 通过产品角色构造者生产新鲜豆腐
$toFuBuilder = new CreateBuilderToFu();
$director->setBuilder($toFuBuilder);
$newToFu     = $director->startBuild();
$newToFu->showToFu();

// 通过产品角色构造者生产麻婆豆腐
$maPoToFu = new CreateBuilderMaPoToFu();
$director->setBuilder($maPoToFu);
$director->startBuild()->showToFu();

我是夕阳何处寻,期待和优秀的你一起同行!

夕阳何处寻

2019年12月25日

请登录后再评论