Purpose:
Builder is an interface that build parts of a complex object.
Sometimes, if the builder has a better knowledge of what it builds, this interface could be an abstract class with default methods.
If you have a complex inheritance tree for objects, it is logical to have a complex inheritance tree for builders too.
在这个模式里面,Director 只需要接收一个builder,并且指挥builder去做事情,最后返回一个Vehicle。在builder class里面,定义了如何去做事情。
如果没有Director,在我们每次想得到不同Vehicle Instance之前,都得让builder去做一遍Director里定义的方法。
Director.php
<?php namespace DesignPatterns\Creational\Builder; use DesignPatterns\Creational\Builder\Parts\Vehicle; /** * Director is part of the builder pattern. It knows the interface of the builder * and builds a complex object with the help of the builder * * You can also inject many builders instead of one to build more complex objects */ 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; abstract class Vehicle { /** * @var object[] */ private $data = []; /** * @param string $key * @param object $value */ public function setPart($key, $value) { $this->data[$key] = $value; } }
Parts/Truck.php
<?php namespace DesignPatterns\Creational\Builder\Parts; class Truck extends Vehicle { }
Parts/Car.php
<?php namespace DesignPatterns\Creational\Builder\Parts; class Car extends Vehicle { }
Parts/Engine.php
<?php namespace DesignPatterns\Creational\Builder\Parts; class Engine { }
Parts/Wheel.php
<?php namespace DesignPatterns\Creational\Builder\Parts; class Wheel { }
Parts/Door.php
<?php namespace DesignPatterns\Creational\Builder\Parts; class Door { }
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); } }
原文:https://www.cnblogs.com/victorchen/p/10826006.html