Skip to content

Instantly share code, notes, and snippets.

@aliselcuk
Last active May 27, 2022 13:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aliselcuk/59e702e55d26de15c7fa2ef7907373c2 to your computer and use it in GitHub Desktop.
Save aliselcuk/59e702e55d26de15c7fa2ef7907373c2 to your computer and use it in GitHub Desktop.
PHP Builder Pattern Example
<?php
/**
* An extremely basic class for creating people objects
*/
class Person
{
public $employed;
public $gender;
const GENDER_MALE = "Male";
const GENDER_FEMALE = "Female";
}
/**
* All people builder should implement this interface
*/
interface PersonBuilderInterface
{
public function setGender();
public function setEmployed();
public function getResult();
}
/**
* builder to create an employed male
*/
class EmployedMaleBuilder implements PersonBuilderInterface
{
private $person;
public function __construct()
{
$this->person = new Person();
}
public function setGender()
{
$this->person->gender = Person::GENDER_MALE;
}
public function setEmployed()
{
$this->person->employed = true;
}
public function getResult()
{
return $this->person;
}
}
/**
* builder to create an unemployed male
*/
class UnemployedMaleBuilder implements PersonBuilderInterface
{
private $person;
public function __construct()
{
$this->person = new Person();
}
public function setGender()
{
$this->person->gender = Person::GENDER_MALE;
}
public function setEmployed()
{
$this->person->employed = false;
}
public function getResult()
{
return $this->person;
}
}
/**
* builder to create an employed female
*/
class EmployedFemaleBuilder implements PersonBuilderInterface
{
private $person;
public function __construct()
{
$this->person = new Person();
}
public function setGender()
{
$this->person->gender = Person::GENDER_FEMALE;
}
public function setEmployed()
{
$this->person->employed = true;
}
public function getResult()
{
return $this->person;
}
}
/**
* builder to create an unemployed female
*/
class UnemployedFemaleBuilder implements PersonBuilderInterface
{
private $person;
public function __construct()
{
$this->person = new Person();
}
public function setGender()
{
$this->person->gender = Person::GENDER_FEMALE;
}
public function setEmployed()
{
$this->person->employed = false;
}
public function getResult()
{
return $this->person;
}
}
/**
* The director class is part of the builder patter, the build method should be passed a builder.
* The build method should than call all of the builder methods and return a Person object
*/
class PersonDirector
{
public function build(PersonBuilderInterface $builder)
{
$builder->setGender();
$builder->setEmployed();
return $builder->getResult();
}
}
$director = new PersonDirector();
$employedMaleBuilder = new EmployedMaleBuilder();
$unemployedMaleBuilder = new UnemployedMaleBuilder();
$employedFemaleBuilder = new EmployedFemaleBuilder();
$unemployedFemaleBuilder = new UnemployedFemaleBuilder();
/**
* object(Person)#3 (2) {
* (
* ["employed"] => bool(true)
* ["gender"] => string(4) "Male"
* )
*/
$employedMale = $director->build($employedMaleBuilder);
/**
* object(Person)#5 (2) {
* (
* ["employed"] => bool(false)
* ["gender"] => string(4) "Male"
* )
*/
$unemployedMale = $director->build($unemployedMaleBuilder);
/**
* object(Person)#7 (2) {
* (
* ["employed"] => bool(true)
* ["gender"] => string(4) "Female"
* )
*/
$employedFemale = $director->build($employedFemaleBuilder);
/**
* object(Person)#11 (2) {
* (
* ["employed"] => bool(false)
* ["gender"] => string(4) "Female"
* )
*/
$unemployedFemale = $director->build($unemployedFemaleBuilder);
@cotton-more
Copy link

What if a builder needs external data?

For instance, the result should be a Person object with a birthdate. For employers, it also requires a date when the person hired and department. And for unemployed – a date when this person fired.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment