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