Creating Objects Dynamically with Factory Methods

Welcome to the third part of a series that shows you how to implement factory methods in PHP 5. Made up of six tutorials, this series uses numerous friendly code samples to illustrate how to implement the Factory and Singleton design patterns within your PHP 5-based web applications. In this way, they will be able to build objects in a truly efficient manner.

And now that you know what to expect from this set of articles, it’s time to review the topics that were discussed in the last one. In that installment of the series, I explained how to build a simple factory class that could return to client code objects that represented a couple of common web form elements, including input text boxes and text areas.

Naturally, these objects were created by a basic factory method, which was always called in the object context, that is, dynamically. However, the most relevant aspect to note with reference to the way that this factory class was defined was the existence of a static method called “getInstance(),” which returned Singletons of the class in question.

Also, it’s worth mentioning that the implementation of this static method followed a simple, important rule: it did not deal with multiple instances of the factory class within a given script. Even though this approach does permit you to work with a unique instance of the mentioned class, it can be improved even further.

But how can this be done? Well, as a rule of thumb, classes that create an instance of themselves should implement a static factory method that returns Singletons, while factory classes that spawn other objects should have only a static factory method.

The form element factory class created in the previous article falls under this last category. Therefore, in the next few lines I’m going to change the declaration of its factory method to make it static. This way, no instance of this class will be required to create form element objects.

If this explanation sounds rather confusing to you, then dissipate that cloud of doubt and begin reading now!

{mospagebreak title=Review: implementing the Singleton pattern inside a factory class}

Before I start explaining how to change the definition of the factory class built in the preceding tutorial to make its factory method static, I’d like to review how this class could be used in its original state to create a pair of web form element objects very quickly.

That being said, here are the definitions corresponding to the classes that render those web form elements. Look at them, please:

// define TextBox class

class TextBox

{

private $name = ‘mytextbox’;

private $id = ‘textbox’;

private $class = ‘textbox’;

private $maxlength = 20;

 

// constructor

public function __construct($attributes = array())

{

if (empty($attributes) === FALSE)

{

foreach ($attributes as $attribute => $value)

{

if (in_array($attribute, array(‘name’, ‘id’, ‘class’, ‘maxlength’)) and empty($value) === FALSE)

{

$this->$attribute = $value;

}

}

}

}

 

// renders input text box element

public function render()

{

return ‘<input type="text" name="’ . $this->name . ‘" id="’ . $this->id . ‘" class="’ . $this->class . ‘" maxlength="’ . $this->maxlength . ‘" />’;

}

}

 

 

// define TextArea class

class TextArea

{

private $name = ‘mytextarea’;

private $id = ‘textarea’;

private $class = ‘textarea’;

private $rows = 10;

private $cols = 20;

 

// constructor

public function __construct($attributes = array())

{

if (empty($attributes) === FALSE)

{

foreach ($attributes as $attribute => $value)

{

if (in_array($attribute, array(‘name’, ‘id’, ‘class’, ‘rows’, ‘cols’)) and empty($value) === FALSE)

{

$this->$attribute = $value;

}

}

}

}

 

// renders textarea element

public function render()

{

return ‘<textarea name="’ . $this->name . ‘" id="’ . $this->id . ‘" class="’ . $this->class . ‘" rows="’ . $this->rows . ‘" cols="’ . $this->cols . ‘"></textarea>’;

}

}

Undeniably, understanding the driving logic of the two classes above should be a straightforward process for you. All they do is return via their “render()” public method the markup required to display on screen some input text boxes and text areas, in accordance with the arguments passed to their constructors. Period.

Moving forward, it’s time to show the definition of the factory class, which returns to client code instances of the previous classes. In addition, it’s valid to notice that this factory class implements a static “getInstance()” method, which simply returns Singletons of that class.

Here’s how this sample class looks:

class FormElementFactory

{

private static $instance = NULL;

 

// get Singleton instance of form element factory class

public static function getInstance()

{

if (self::$instance === NULL)

{

self::$instance = new FormElementFactory;

}

return self::$instance;

}

public function factory($formElement, $attributes = array())

{

if ($formElement === ‘textbox’ or $formElement === ‘textarea’)

{

return new $formElement($attributes);

 }

}

}

As seen above, the “factory()” method defined within the previous class is tasked with spawning HTML form element objects, while its “getInstance()” static method is responsible for returning only one instance of the class. Simple to code and read, right?

So far, so good. Having shown you the definitions corresponding to all of these sample classes, it’s time to set up an example that puts them to work together. So, here’s a simple script that does exactly that. Pay close attention to it:

// create instance of FormElementFactory class using its ‘getInstance()’ method

$formFactory = FormElementFactory::getInstance();

// create some form elements objects

$texBox = $formFactory->factory(‘textbox’);

$textArea = $formFactory->factory(‘textarea’);

// display form elements

echo $texBox->render() . ‘<br />’ . $textArea->render();

There you have it. As this script shows, it’s extremely easy to take advantage of the functionality provided by the factory class to create a couple of web form element objects. Finally, once those objects are brought into existence, displaying their markup is only a matter of calling their “render()” method and nothing else.

However, not everything looks good in this example, unfortunately. To spawn the corresponding web form element objects, at least one single instance of the factory class had to be created. This necessity can be avoided easily by calling its “factory()” method out of the object context.

To do things the right way, however, the method in question should be declared static too. So, in the next section I’m going to introduce this small change into the definition of the pertinent factory class, thus making its factory method much more efficient.

To learn more on this updating process, read the following segment. It’s only one click away.

{mospagebreak title=Defining a static factory method}

To considerably improve the efficiency of the factory class that you saw in the previous segment, I’m going to perform a two-step changing process: first its factory method will be declared static, and then its “getInstance()” method will be removed, since it won’t be required anymore.

That being explained, please have a look at the modified definition of the factory class:

// define FormElementFactory class

 

class FormElementFactory

{

public static function factory($formElement, $attributes = array())

{

if ($formElement === ‘textbox’ or $formElement === ‘textarea’)

{

return new $formElement($attributes);

}

}

}

See how simple it is to turn the sample factory class into a more compact and useful piece of code? I guess you do! Of course, the class’s enhanced definition shows how its static factory method is capable of easily creating web form element objects, and best of all, without having to deal with any instances of the factory itself.

Naturally, if you’re like me, then you’re eager to see how the improved version of the factory class can be used in a concrete case. With that idea in mind, in the final section of this tutorial I’m going to set up an illustrative example that will show how to utilize the class to create some HTML form element objects.

To learn how this example will be developed, click on the link that appears below and read the upcoming segment.

{mospagebreak title=Calling a factory method out of the object scope} 

In the previous section the definition of the sample factory class was subtly modified, and its factory method was turned into a static one — so now we need to see how this specific method can be used for creating web form element objects in a few simple steps.

Thus, below I coded a final script, which clearly demonstrates this process. Here it is:

$texBox = FormElementFactory::factory(‘textbox’);

$textArea = FormElementFactory::factory(‘textarea’);

// display web form elements

echo $texBox->render() . ‘<br />’ . $textArea->render();

Undeniably, the above code fragment shows the advantages of declaring the “factory()” method of the “FormElementFactory” class static, because thanks to this small modification, it’s possible to create a pair of web form element objects without having to mess with any instances of this factory class.

While the previous example is rather primitive, it demonstrates not only how to define a factory method, but how to use it properly, without getting into bad programming habits.

Finally, feel free to edit all of the code samples included in this tutorial, so you can improve your existing skills in factoring objects in PHP 5.

Final thoughts

That’s about it for the moment. Over this third episode of the series, I demonstrated how to use a static factory method to create other objects, which in this particular case were simple representations of HTML form elements, such as text areas and input boxes.

If you reread the previous sentence, you’ll realize that this factory method was charged with creating instances of other classes. Nonetheless, it’s also possible to define factory methods that create instances of its originating class.

That will be exactly the topic that I plan to cover in the next tutorial. So, now that you’re aware of the subject of that article, you can’t miss it!

[gp-comments width="770" linklove="off" ]
antalya escort bayan antalya escort bayan