Builder Pattern in Zend Framework

When we want to implement one thing in different ways, we think of builder design pattern. It’s like a building, when, design has been done, though handled by different engineers directing different construction teams, eventually the building will be the same.

 

Here I have to say something about the different between the builder pattern and the factory pattern. In fact as the name implies factory, It provides products, such as rice cooker, microwave ovens and so on. But the builder is more responsible, it provides the different finished in different ways. For example cooking, we can use rice cooker, but microwave ovens can also be used.

 

Zend_Feed module in Zend Framework has already implemented the builder design pattern to allow users to achieve their own customized content feed :

 

 

The source code below is simplified :

 

[codesyntax lang=”php”]

// builder interface
interface Zend_Feed_Builder_Interface
{
    public function getHeader();
    public function getEntries();
}

[/codesyntax]

 

Default builder provided by Zend_Feed :

 

/**
* @see Zend_Feed_Builder_Interface
*/

require_once 'Zend/Feed/Builder/Interface.php';
/**
* @see Zend_Feed_Builder_Header
*/

require_once 'Zend/Feed/Builder/Header.php';
/**
* @see Zend_Feed_Builder_Entry
*/

require_once 'Zend/Feed/Builder/Entry.php';
/**
* Zend_Feed_Builder implements the Zend_Feed_Builder_Interface interface
* Users can create their own customized builder through Zend_Feed_Builder_Interface interface
*/

class Zend_Feed_Builder implements Zend_Feed_Builder_Interface
{
private $_header;
private $_entries = array();
// ......
public function __construct(array $data)
{
// ......
$this->_header = new Zend_Feed_Builder_Header($data['title'], $data['link'], $data['charset']);
foreach ($data as $row) {
// ......
$entry = new Zend_Feed_Builder_Entry($row['title'], $row['link'], $row['description']);
$this->_entries[] = $entry;
}
}
// Zend_Feed_Builder_Interface interface function
public function getHeader()
{
return $this->_header;
}
// Zend_Feed_Builder_Interface interface function
public function getEntries()
{
return $this->_entries;
}
// ......
}

 

Notice that we can easily implement our own builder through Zend_Feed_Builder_Interface interface, for example :

 

[codesyntax lang=”php”]

class My_Feed_Builder implements Zend_Feed_Builder_Interface
{
public function getHeader()
{
return 'My Header!';
}
public function getEntries()
{
return 'My Entries!';
}
}

[/codesyntax]

 

Then let’s take a look at Zend_Feed_Abstract abstract class. It acts like a director in the builder pattern within Zend_Feed module. Its responsibility is to choose and aggregate the builder that user provide, and then cure the semi-manufactured into perfect goods.

 

[codesyntax lang=”php”]

/**
* Zend_Feed_Abstract abstract class
*/

abstract class Zend_Feed_Abstract extends Zend_Feed_Element implements Iterator
{
// Header and Entries are provided by $builder
public function __construct($uri = null, $string = null, Zend_Feed_Builder_Interface $builder = null)
{
// ......
$this->_mapFeedHeaders($builder->getHeader());
$this->_mapFeedEntries($builder->getEntries());
}
}

[/codesyntax]

 

The example feed data sets is from a simple array :

 

[codesyntax lang=”php”]

$data = array('author' => 'kim'
              'description' => 'my data');

// Use default builder
require_once 'Zend/Feed/Builder.php';
$atom = new Zend_Feed_Atom(null, null, new Zend_Feed_Builder($data));

// Use my own builder
require_once 'My/Feed/Builder.php';
$myAtom = new Zend_Feed_Atom(null, null, new My_Feed_Builder($data));

[/codesyntax]

 

The builder design pattern has provide a flexible mechanism to create the object and data collections, which is really the assuring for the extensiblity of application.

 

Posted in Design Patterns | Tagged , | Leave a comment