PHP很简单PHP经验分享程序员技术栈

设计模式[创建型]06--建造者模式(Builder)

2019-06-05  本文已影响13人  四月不见

一、简介

无论是在现实世界中还是在软件系统中,都存在一些复杂的对象,它们拥有多个组成部分,如汽车,它包括车轮、方向盘、发送机等各种部件。而对于大多数用户而言,无须知道这些部件的装配细节,也几乎不会使用单独某个部件,而是使用一辆完整的汽车,可以通过建造者模式对其进行设计与描述,建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象。用户只需要指定复杂对象的类型就可以得到该对象,而无须知道其内部的具体构造细节。

复杂对象相当于一辆有待建造的汽车,而对象的属性相当于汽车的部件,建造产品的过程就相当于组合部件的过程。由于组合部件的过程很复杂,因此,这些部件的组合过程往往被“外部化”到一个称作建造者的对象里,建造者返还给客户端的是一个已经建造完毕的完整产品对象,而用户无须关心该对象所包含的属性以及它们的组装方式,这就是建造者模式的模式动机。

建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。建造者模式属于对象创建型模式。根据中文翻译的不同,建造者模式又可以称为生成器模式。

二、场景

比如:去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"。

使用场景:
1)需要生成的对象具有复杂的内部结构。
2)需要生成的对象内部属性本身相互依赖。

建造者模式主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

三、类结构

建造者模式包含如下角色:

角色 简述
Builder 抽象建造者
ConcreteBuilder 具体建造者
Director 指挥者
Product 产品角色

四、UML图

五、代码分析

下面以建造汽车为例。

1、抽象建造者

interface BuilderInterface
{
    public function createVehicle();

    public function addWheel();

    public function addEngine();

    public function addDoors();

    public function getVehicle();
}

2、具体建造者

// 建造大卡车
class TruckBuilder implements BuilderInterface
{
    /**
     * @var Truck
     */
    private $truck;

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

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

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

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

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

// 建造小汽车
class CarBuilder implements BuilderInterface
{
    /**
     * @var Car
     */
    private $car;

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

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

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

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

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

3、指挥者

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

        return $builder->getVehicle();
    }
}

4、产品角色

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

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

class Truck extends Vehicle{
}
class Car extends Vehicle{
}

// 产品部件
class Engine{
}
class Wheel{
}
class Door{
}

5、使用案例

$diretor = new Director();
$myTruck = $diretor->build(new TruckBuilder());
$myCar = $diretor->build(new CarBuilder());

var_dump($myTruck);
var_dump($myCar);

输出结果:

object(Truck)#3 (1) {
  ["data":"Vehicle":private]=>
  array(10) {
    ["rightDoor"]=>
    object(Door)#4 (0) {
    }
    ["leftDoor"]=>
    object(Door)#5 (0) {
    }
    ["trunkLid"]=>
    object(Door)#6 (0) {
    }
    ["truckEngine"]=>
    object(Engine)#7 (0) {
    }
    ["wheel1"]=>
    object(Wheel)#8 (0) {
    }
    ["wheel2"]=>
    object(Wheel)#9 (0) {
    }
    ["wheel3"]=>
    object(Wheel)#10 (0) {
    }
    ["wheel4"]=>
    object(Wheel)#11 (0) {
    }
    ["wheel5"]=>
    object(Wheel)#12 (0) {
    }
    ["wheel6"]=>
    object(Wheel)#13 (0) {
    }
  }
}
object(Car)#14 (1) {
  ["data":"Vehicle":private]=>
  array(7) {
    ["rightDoor"]=>
    object(Door)#15 (0) {
    }
    ["leftDoor"]=>
    object(Door)#16 (0) {
    }
    ["engine"]=>
    object(Engine)#17 (0) {
    }
    ["wheelLF"]=>
    object(Wheel)#18 (0) {
    }
    ["wheelRF"]=>
    object(Wheel)#19 (0) {
    }
    ["wheelLR"]=>
    object(Wheel)#20 (0) {
    }
    ["wheelRR"]=>
    object(Wheel)#21 (0) {
    }
  }
}

六、特点

1、优点:

2、缺点:

3、注意事项:
与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。

上一篇 下一篇

猜你喜欢

热点阅读