Builder Design Pattern
Builder Design Pattern
The Builder pattern is one of the most widely used creational design patterns. It lets you construct complex objects step by step, separating the construction process from the final representation. The same construction steps can produce entirely different outputs depending on the builder you use.
A separate builder class handles the construction. It takes care of all the necessary steps and returns the finished product.
The pattern consists of several parts:
- Director: Controls the construction process. It receives a builder and instructs it to carry out the steps.
- Builder: Defines the interface for the steps required to create the product.
- Concrete Builder: Implements the Builder interface and provides the actual construction logic for each step.
- Product: The final object that the construction process produces.
The typical flow looks like this:
- The client creates a Concrete Builder.
- The client creates a Director, passing the builder to it.
- The Director calls the appropriate methods on the builder to construct the product.
- The client retrieves the finished product from the builder.
Advantages
- Separation of concerns: Construction logic lives in the builder, completely separate from the final representation. This makes it straightforward to produce different representations from the same steps.
- Encapsulation: The construction process is hidden inside the builder class, keeping client code clean.
- Better control: By swapping builders, the Director can produce entirely different products without changing its own logic.
- Easy modification: Changing how the product is built requires only an update to the builder, not the client or the Director.
Real World Example
The following example creates a car using the Builder pattern. The car has a model, a year, and a colour.
<?php
// Product class
class Car {
private $model;
private $year;
private $color;
public function setModel($model) {
$this->model = $model;
}
public function setYear($year) {
$this->year = $year;
}
public function setColor($color) {
$this->color = $color;
}
public function getInfo() {
return "Car Model: " . $this->model . ", Year: " . $this->year . ", Color: " . $this->color;
}
}
// Builder interface
interface CarBuilderInterface {
public function setModel($model);
public function setYear($year);
public function setColor($color);
public function getResult(): Car;
}
// Concrete Builder
class CarBuilder implements CarBuilderInterface {
private $car;
public function __construct() {
$this->car = new Car();
}
public function setModel($model) {
$this->car->setModel($model);
return $this;
}
public function setYear($year) {
$this->car->setYear($year);
return $this;
}
public function setColor($color) {
$this->car->setColor($color);
return $this;
}
public function getResult(): Car {
return $this->car;
}
}
// Director
class CarDirector {
private $builder;
public function __construct(CarBuilderInterface $builder) {
$this->builder = $builder;
}
public function buildTesla() {
$this->builder->setModel('Tesla')
->setYear('2022')
->setColor('Black');
}
}
// Client code
$builder = new CarBuilder();
$director = (new CarDirector($builder))->buildTesla();
$car = $builder->getResult();
echo $car->getInfo(); // Output: "Car Model: Tesla, Year: 2022, Color: Black"