Posted on 13-11-2009
Filed Under (PHP) by Romi

Picking up on the last post, and following Alex’s advice, I have decided to rewrite the example for the Builder pattern. Read about the new and improved form Builder…

Now, I mainly use PHP (as you can obviously tell) and some details are harder to notice (or understand, for that matter) than in other languages (like, let’s say, Flex). I know that’s not such a good excuse, but bare with me, the new version will clearly show what I left behind in the previous one. So, if you have read the last post (carefully, of course), the main idea is that we use a particular type of builder to create a particular type of form item (text input, radio button or text area) by rewriting the createElement() function, for each builder type.

Naturally, a text builder builds a form with a text input, a radio one, with radio buttons, as for the area builder… well, let’s just take a wild stab in the dark, shall we? The final product will be a form with only one kind of items. To quote Alex, “it’s half-wrong” (I’d would have preferred “it’s half-right”), and I agree with him. Why? Well, this way the builders are constrained to create only one type of items which compose the final product. And the immediate implication of this fact is that each added builder will need to rewrite this function. That makes extending not really difficult, but more than it should be. How do we fix this? First thing we need to do is to make a general item creation function defined by the Abstract builder, and a new builder will overwrite this function ONLY IF that may be the case. This way we can focus on each builder’s particularities, for instance, the constructor.

A less significant matter was the createSubmit() function. Isn’t the submit button also a form element? Sure it is, so we wouldn’t need a “specialized” function for it. So, rewrite the Abstract builder accordingly and it will look like this:

class AbstractBuilder
{
    public function createElement( $type, $name, $value = NULL )
    {
         $element = new Element();
         $element->setType( $type );
         $element->setName( $name );
         if( $value )
             $element->setValue( $value );
        array_push( $this->_storedElements, $element );
 }
 
    public function renderForm()
    {
        echo "\r\n".'<form method="post" style="border:'.$this->_borderThickness.'px solid #'.$this->_borderColor.'; display:table-cell; padding:'.$this->_padding.'px;">'."<table>\r\n";
 
        foreach($this->_storedElements as $product)
        {
            if( $product->getType() != "submit" && $product->getType() != "area" )
                echo $product->getValue().'<input type="'.$product->getType().'" name="'.$product->getName().'" value="'.$product->getValue().'" /><br />'."\r\n";
            else
                if($product->getType() == "area")
                    echo '<textarea name="'.$product->getName().'" rows="5" cols="30"></textarea><br />'."\r\n";
                else
                    echo '<input type="'.$product->getType().'" name="'.$product->getName().'" value="'.$product->getValue().'" /><br />'."\r\n";
        }
 
        echo "</table>\r\n</form>\r\n";
    }
 
    protected $_storedElements    = array();
    protected $_borderColor         = "000000";
    protected $_borderThickness   = 1;
    protected $_padding              = 0;
}

Much better. I added the last three member variables so the difference between final products (i.e. forms) will have a “visual touch”.

Enough about the abstract builer, what about the concrete ones? Like I said, since all elements are built in the same way, a concrete builder class doesn’t need to have a createElement() function defined, but it can rewrite it if it needs to. So how does a concerete builder class look? Easy, just define a constructor and you have a builder:

class TextFormBuilder extends AbstractBuilder
{
    public function __construct()
    {
        $this->_borderColor        = "ff0000";
        $this->_borderThickness  = 2;
        $this->_padding             = 10;
    }
}

I only showed the TextFormBuilder here because the other two just vary these values. I know, I know… I should have changed their name too, but this way it’s easier to understand the modifications. Also, the new source code is available here, and the demo of the application, here.

(0) Comments    Read More   
Post a Comment
Name:
Email:
Website:
Comments: