PHP设计模式之建造者模式(Builder Pattern)

一、什么是建造者模式                

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

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

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

【释义】

使用生活中的例子来解释建造者模式:

        例如:汽车生产,有不同厂家,不同种类的汽车。例如奔驰,宝马,奥迪又或者是卡车,轿车,SUV等。每种汽车的生产有相同之处,但又有区别。这个时候就可以利用到建造者思想模式嵌套进去。

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

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

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

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

Director:指挥者,构造一个使用Builder接口的对象。它主要是用于创建一个复杂的对象。它主要有两个作用:①是隔离了客户与对象的生产过程,②负责控制产品对象的生产过程。

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

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

四、建造者模式优缺点

优点

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

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

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

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

缺点

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

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

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

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

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

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

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

六、UML类图

七、示例代码

Director.php

<?php

namespace DesignPatterns\Creational\Builder;

use DesignPatterns\Creational\Builder\Parts\Vehicle;

/**
 * Director 类是建造者模式的一部分。 它可以实现建造者模式的接口
 * 并在构建器的帮助下构建一个复杂的对象
 *
 * 您也可以注入许多构建器而不是构建更复杂的对象
 */
class Director
{
    public function build(BuilderInterface $builder): Vehicle
    {
        $builder->createVehicle();
        $builder->addDoors();
        $builder->addEngine();
        $builder->addWheel();

        return $builder->getVehicle();
    }
}

BuilderInterface.php

<?php

namespace DesignPatterns\Creational\Builder;

use DesignPatterns\Creational\Builder\Parts\Vehicle;

interface BuilderInterface
{
    public function createVehicle();

    public function addWheel();

    public function addEngine();

    public function addDoors();

    public function getVehicle(): Vehicle;
}

TruckBuilder.php

<?php

namespace DesignPatterns\Creational\Builder;

use DesignPatterns\Creational\Builder\Parts\Vehicle;

class TruckBuilder implements BuilderInterface
{
    /**
    * @var Parts\Truck
    */
    private $truck;

    public function addDoors()
    {
        $this->truck->setPart('rightDoor', new Parts\Door());
        $this->truck->setPart('leftDoor', new Parts\Door());
    }

    public function addEngine()
    {
        $this->truck->setPart('truckEngine', new Parts\Engine());
    }

    public function addWheel()
    {
        $this->truck->setPart('wheel1', new Parts\Wheel());
        $this->truck->setPart('wheel2', new Parts\Wheel());
        $this->truck->setPart('wheel3', new Parts\Wheel());
        $this->truck->setPart('wheel4', new Parts\Wheel());
        $this->truck->setPart('wheel5', new Parts\Wheel());
        $this->truck->setPart('wheel6', new Parts\Wheel());
    }

    public function createVehicle()
    {
        $this->truck = new Parts\Truck();
    }

    public function getVehicle(): Vehicle
    {
        return $this->truck;
    }
}

CarBuilder.php

<?php

namespace DesignPatterns\Creational\Builder;

use DesignPatterns\Creational\Builder\Parts\Vehicle;

class CarBuilder implements BuilderInterface
{
    /**
    * @var Parts\Car
    */
    private $car;

    public function addDoors()
    {
        $this->car->setPart('rightDoor', new Parts\Door());
        $this->car->setPart('leftDoor', new Parts\Door());
        $this->car->setPart('trunkLid', new Parts\Door());
    }

    public function addEngine()
    {
        $this->car->setPart('engine', new Parts\Engine());
    }

    public function addWheel()
    {
        $this->car->setPart('wheelLF', new Parts\Wheel());
        $this->car->setPart('wheelRF', new Parts\Wheel());
        $this->car->setPart('wheelLR', new Parts\Wheel());
        $this->car->setPart('wheelRR', new Parts\Wheel());
    }

    public function createVehicle()
    {
        $this->car = new Parts\Car();
    }

    public function getVehicle(): Vehicle
    {
        return $this->car;
    }
}

Parts/Vehicle.php

<?php

namespace DesignPatterns\Creational\Builder\Parts;

/**
* production vehicle Parts - Wheel
*/
class Wheel{}

/**
* production vehicle Parts - Engine
*/
class Engine{}

/**
* production vehicle Parts - Door
*/
class Door{}

abstract class Vehicle
{
    /**
    * @var object[]
    */
    private $data = [];

    /**
    * @param string $key
    * @param object $value
    */
    public function setPart($key, $value)
    {
        $this->data[$key] = $value;
    }
}

Parts/Car.php

<?php

namespace DesignPatterns\Creational\Builder\Parts;

class Car extends Vehicle
{
}

Parts/Truck.php

<?php

namespace DesignPatterns\Creational\Builder\Parts;

class Truck extends Vehicle
{
}

测试

Tests/DirectorTest.php

<?php

namespace DesignPatterns\Creational\Builder\Tests;

use DesignPatterns\Creational\Builder\Parts\Car;
use DesignPatterns\Creational\Builder\Parts\Truck;
use DesignPatterns\Creational\Builder\TruckBuilder;
use DesignPatterns\Creational\Builder\CarBuilder;
use DesignPatterns\Creational\Builder\Director;
use PHPUnit\Framework\TestCase;

class DirectorTest extends TestCase
{
    public function testCanBuildTruck()
    {
        $truckBuilder = new TruckBuilder();
        $newVehicle = (new Director())->build($truckBuilder);

        $this->assertInstanceOf(Truck::class, $newVehicle);
    }

    public function testCanBuildCar()
    {
        $carBuilder = new CarBuilder();
        $newVehicle = (new Director())->build($carBuilder);

        $this->assertInstanceOf(Car::class, $newVehicle);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
建造者模式Builder Pattern)是一种创建型设计模式,其目的是将一个复杂对象的构造与它的表示分离,使得同样的构建过程可以创建不同的表示。在该模式中,建造者类负责创建一个复杂对象的各个部分,并将这些部分组装起来形成完整的对象。 在PHP中,我们可以通过以下代码实现建造者模式: 1. 创建建造者接口Builder,用于定义构造复杂对象的方法。 ``` interface Builder { public function buildPartA(); public function buildPartB(); public function buildPartC(); public function getResult(); } ``` 2. 创建具体建造者类ConcreteBuilder,实现Builder接口中定义的方法,用于构造一个具体对象。 ``` class ConcreteBuilder implements Builder { private $product; public function __construct() { $this->product = new Product(); } public function buildPartA() { $this->product->setPartA('Part A'); } public function buildPartB() { $this->product->setPartB('Part B'); } public function buildPartC() { $this->product->setPartC('Part C'); } public function getResult() { return $this->product; } } ``` 3. 创建产品类Product,用于表示复杂对象。 ``` class Product { private $partA; private $partB; private $partC; public function setPartA($partA) { $this->partA = $partA; } public function setPartB($partB) { $this->partB = $partB; } public function setPartC($partC) { $this->partC = $partC; } public function getParts() { return [$this->partA, $this->partB, $this->partC]; } } ``` 4. 创建指挥者类Director,用于控制建造过程。 ``` class Director { private $builder; public function setBuilder(Builder $builder) { $this->builder = $builder; } public function construct() { $this->builder->buildPartA(); $this->builder->buildPartB(); $this->builder->buildPartC(); } } ``` 5. 在客户端代码中,使用指挥者类Director来构造一个具体对象。 ``` $builder = new ConcreteBuilder(); $director = new Director(); $director->setBuilder($builder); $director->construct(); $product = $builder->getResult(); print_r($product->getParts()); ``` 输出结果: ``` Array ( [0] => Part A [1] => Part B [2] => Part C ) ``` 以上就是基于PHP实现建造者模式模型的示例代码。通过该模式,我们可以将一个复杂对象的构造过程与表示分离,从而使得代码更加灵活和易于维护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值