05
02月
2020
建造者模式
模式定义
将一个复杂对象的建造与调用者分离。调用者只需要给出指定对象的类型和内容,建造者模式负责按照顺寻创建复杂对象.
建造者模式的优势
易于解耦,将产品本身与创建的过程分离,可以使用相同的创建过程来创建不同的产品. 易于精确的控制对象,将复杂对象的创建划分在不同的方法中,创建过程更加清晰 易于扩展,增加新的建造者无需修改原来的类库
建造者模式的缺陷
建造者模式的产品具有较多的共同点,组成部分类似。如果产品之间差异较大,则不适合 如果产品的内部变化复杂,需要定义更多具体的建造者来配合,导致系统变的庞大
代码示例
Builder\Director.class.php
<?php
namespace Builder;
class Director
{
public function build($builder)
{
$builder->createVehicle();
$builder->addDoors();
$builder->addEngine();
$builder->addWheel();
return $builder->getVehicle();
}
}Builder\BuilderInterface.class.php
<?php
namespace Builder;
interface BuilderInterface
{
public function createVehicle();
public function addDoors();
public function addEngine();
public function addWheel();
public function getVehicle();
}Builder\BikeBuilder.class.php
<?php
namespace Builder;
use Builder\Parts\Bike;
use Builder\Parts\Wheel;
use Builder\Parts\Engine;
class BikeBuilder implements BuilderInterface
{
protected $bike;
public function createVehicle()
{
$this->bike = new Bike();
}
public function addWheel()
{
$this->bike->setPart('forwardWheel', new Wheel());
$this->bike->setPart('rearWheel', new Wheel());
}
public function addEngine()
{
$this->bike->setPart('engine', new Engine());
}
public function addDoors()
{
}
public function getVehicle()
{
return $this->bike;
}
}Builder\CarBuilder.class.php
<?php
namespace Builder;
use Builder\Parts\Door;
use Builder\Parts\Engine;
use Builder\Parts\Wheel;
use Builder\Parts\Car;
class CarBuilder implements BuilderInterface
{
protected $car;
public function createVehicle()
{
$this->car = new Car();
}
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 addEngine()
{
$this->car->setPart('engine', new Engine());
}
public function addDoors()
{
$this->car->setPart('rightdoor', new Door());
$this->car->setPart('leftdoor', new Door());
}
public function getVehicle()
{
return $this->car;
}
}Builder\Parts\Vehicle.class.php
<?php
namespace Builder\Parts;
abstract class Vehicle
{
protected $data;
public function setPart($key, $value)
{
$this->data[$key] = $value;
}
}Builder\Parts\Bike.class.php
<?php
namespace Builder\Parts;
class Bike extends Vehicle
{
}Builder\Parts\Car.class.php
<?php
namespace Builder\Parts;
class Car extends Vehicle
{
}Builder\Parts\Door.class.php
<?php
namespace Builder\Parts;
class Door
{
}Builder\Parts\Engine.class.php
<?php
namespace Builder\Parts;
class Engine
{
}Builder\Parts\Wheel.class.php
<?php
namespace Builder\Parts;
class Wheel
{
}Builder\BuilderTest.php
<?php
spl_autoload_register(function ($className){
$className = str_replace("\\", "/", $className);
include $className . ".class.php";
});
use Builder\Director;
use Builder\BikeBuilder;
use Builder\CarBuilder;
$director = new Director();
$bike = $director->build(new BikeBuilder());
$car = $director->build(new CarBuilder());
var_dump($bike);
var_dump($car);测试示例:
php Builder/BuilderTest.php
输出:
object(Builder\Parts\Bike)#4 (1) {
["data":protected]=>
array(3) {
["engine"]=>
object(Builder\Parts\Engine)#5 (0) {
}
["forwardWheel"]=>
object(Builder\Parts\Wheel)#6 (0) {
}
["rearWheel"]=>
object(Builder\Parts\Wheel)#7 (0) {
}
}
}
object(Builder\Parts\Car)#8 (1) {
["data":protected]=>
array(7) {
["rightdoor"]=>
object(Builder\Parts\Door)#9 (0) {
}
["leftdoor"]=>
object(Builder\Parts\Door)#10 (0) {
}
["engine"]=>
object(Builder\Parts\Engine)#11 (0) {
}
["wheelLF"]=>
object(Builder\Parts\Wheel)#12 (0) {
}
["wheelRF"]=>
object(Builder\Parts\Wheel)#13 (0) {
}
["wheelLR"]=>
object(Builder\Parts\Wheel)#14 (0) {
}
["wheelRR"]=>
object(Builder\Parts\Wheel)#15 (0) {
}
}
}总结
建造者模式和抽象工厂模式很像,总体上,建造者模式仅仅只比抽象工厂模式多了一个“导演类”的角色。与抽象工厂模式相比,建造者模式一般用来创建更为复杂的对象,因为对象的创建过程更为复杂,因此将对象的创建过程独立出来组成一个新的类 —— 导演类。也就是说,抽像工厂模式是将对象的全部创建过程封装在工厂类中,由工厂类向客户端提供最终的产品;而建造者模式中,建造者类一般只提供产品类中各个组件的建造,而将完整建造过程交付给导演类。由导演类负责将各个组件按照特定的规则组建为产品,然后将组建好的产品交付给客户端。
代码地址:https://github.com/798256478/design-patterns/tree/master/Builder