Design Patterns PHP - Builder Java


1) What have we at beginning ?

We have simple relation one to many. We have some abstract "Product" which can have many elements which we name "ProductElement"


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

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

}

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

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

}





2) How we create these objects ?

We have some client in which we just call constructor of product and next we add elements to it.

$product = new Product();
$product->addElement(new ProductElement('name1'));
$product->addElement(new ProductElement('name2'));
$product->addElement(new ProductElement('name3'));
$product->addElement(new ProductElement('name4'));




So the essence of issue is creating products. Let's think a little of above solution.

3) What are the disadvantages ?

First of all we create explicitly instances of product and its elements. Client must to know explicitly names of class which implements "Product" and "ProductElement"
It's not good, we don't want this, we want to encapsulate this. We wan't to loose coupling between product and client.

Note: Client shouldn't be bothered information which class actually implement "Product". He should only receive some object which meets "Product" interface, nothing more


So we need to provide solution in which we don't give information to client about objects which are concrete implementation.

Another problem.

It's desirable to be able create product many times in many places. In above code it's bothersome. We would like to present some nicer interface for client.

Note: We can call "addElement" one time, two times, or more: three, four, five ...
Every time we can add different elements. So actually "Product" is designed for representing compound objects even if it has one method. So "Builder" here is strongly advisable


4) How we can improve this ?

We can move creating special object named "Builder" for creating "Product" objects. Let's move to step 2.