Design Patterns PHP - Builder Java

1) What have we done ?

Create "Builder" interface responsible for creating "Product"


interface Builder
{
    /**
     * @return Builder
     */
    public function create();

    /**
     * @param string $name
     * @return Builder
     */
    public function add($name);

    /**
     * @return Product
     */
    public function build();

}

class BuilderImpl implements Builder
{
    /**
     * @var Product
     */
    private $product;

    /**
     * @return Builder
     */
    public function create()
    {
        $this->product = new ProductImpl();

        return $this;
    }

    /**
     * @param string $name
     * @return Builder
     */
    public function add($name)
    {
        $this->product->addElement(new ProductElementImpl($name));

        return $this;
    }

    /**
     * @return Product
     */
    public function build()
    {
        return $this->product;
    }
}




Let's imagine that "Product" and "ProductElement" can have multiple implementation. So let's create interfaces for this object.


interface Product
{
}

interface ProductElement
{

}

class ProductImpl
{
    /**
     * @var ProductElement[]
     */
    private $elements = [];

    public function addElement(ProductElement $productElement)
    {
        $this->elements[] = $productElement;
    }
}

class ProductElementImpl implements ProductElement
{
    /**
     * @var string
     */
    protected $name;

    /**
     * @param string $name
     */
    function __construct($name)
    {
        $this->name = $name;
    }
}




2) How we crate products in clients


/** @var Builder $builder */
$builder = new BuilderImpl();

$product = $builder->create()
    ->add('element1')
    ->add('element2')
    ->add('element3')
    ->add('element4')
    ->build();




3) What are advantages of this solution ?

- we have simple interface in client
- Classes are loosely coupled - client doesn't know implementation classes
- "Product" becomes simpler, creation of this objects are extracted to builder