Using Singletons with Factory Methods in PHP 5

In this second installment of a six-part series on implementing the factory pattern in PHP 5, I explain how to build an improved version of a factory class that returns Singletons of itself to client code.

While this may sound like a cliché, the truth is that building factory methods in PHP 5 is a straightforward process that only requires an intermediate background in working with objects and classes. After all, a factory method is merely a regular class method that returns, when possible, one or more objects to client code — or expressed in other terms, it’s a concrete implementation of the Factory design pattern.

In reality, learning the basics of factory methods is one of those things that every PHP developer must tackle sooner or later. They’re used very frequently in the development of object-oriented web applications, which makes it practically impossible not to deal directly with them at some point.

Of course, if you already went through the introductory part of this series, then you have a pretty clear idea of how to create factory methods using PHP 5. In that tutorial I demonstrated how to create a simple factory class which could spawn a couple of web form element objects for rendering on screen a few basic HTML input boxes and text areas.

However, this example factory class has a serious down side. In its current version it’s necessary to create an instance of it to dynamically call its factory method, and therefore spawn the mentioned web form element objects. Actually, this is considered a bad thing in terms of programming habits, because in this particular case the goal of the factory class is to build other objects, other than its own..so what’s the point in dealing with instances of it? That’s pretty useless.

To address only partially the issue described above, in this second chapter of the series I’m going to introduce some subtle changes into the definition of this factory class, so it can return Singletons of it to client code. This at least will make sure that only one instance of it will be created during the execution of a given script.

Now, let’s and see how to translate the previous concepts to fully-functional PHP 5 code. Let’s go!

{mospagebreak title=Review: building a basic factory class with PHP 5}

In the introduction, I mentioned that the factory class created in the preceding tutorial had a pretty annoying down side, since it was necessary to first create an instance of it to invoke its factory method. Below I’ve listed for you the source code of this class, along with an example that shows how to use it for creating some web form element objects.

First, here are the corresponding classes that render HTML input boxes and text areas. Take a look at them:

// 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>';

}

}

As seen above, the logic implemented by the “TextBox” and “TextArea” classes is quite simple to grasp; in both cases, they accept an array of attributes, which are used by their “render()” method to display the corresponding HTML elements of a web form. The workings of those classes are that simple, really. 

Now, it’s time to show the definition of the factory class, which as I explained before, is responsible for creating both input text and text area objects for further manipulation. 

Here’s how this class was conceived originally:

// define FormElementFactory class

class FormElementFactory

{

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

{

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

{

return new $formElement($attributes);

}

}

}

Obviously, the above class is a wrapper for its factory method, which is the actual workhorse, since it’s tasked with returning to client code the aforementioned web form element objects. As I pointed out earlier, though, while the factory method does its thing as expected, it’s necessary (at least in theory) to create an instance of its originating class to use it.

The following script clearly represents this situation:

$formFactory = new FormElementFactory();

// create some form elements objects

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

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

// display form elements

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

Unquestionably, the form element factory does a decent job when it comes to creating input box and text area objects, but as seen above, this process requires spawning an instance of it first, which is pretty inefficient. Of course, it’s valid to say that the class’s factory method could have been called out of the object scope, that is statically, but this would mean getting ahead of myself.

For the moment, this factory method hasn’t been declared static, so it’s necessary to find a partial solution that permits us to create only a single instance of the previous factory class. But how can this be achieved? Well, I used the term “single” on purpose, so you can pick up the solution very quickly!

Yes, in this case I’m talking about adding to the factory class a method that returns Singletons of it, thus letting us avoid dealing with multiple instances of the class. Sounds pretty interesting, right?

Thus, in the next section I’m going to show you how to incorporate this brand new method inside the previous factory class. Now, click on the link below and keep reading.

{mospagebreak title=Coding a Singleton method} 

Definitely, one of the simplest way to implement the Singleton pattern inside the example form element factory class that you saw before is to add a static method, usually called “getInstance()” (or something similar) that takes care of returning to client code only one instance of it. Period.

To demonstrate in detail how this static method can be coded in a few simple steps, below I reintroduced the definition of the factory class, which this time includes the pertinent “getInstance()” method. Take a look at it, please:

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);

}

}

}

That wasn’t rocket science, wasn’t it? As you can see, now the “FormElementFactory” class implements the Singleton pattern through its “getInstance()” method, which internally uses a $instance static property, to return only a single instance of the class.

While I’m still far from defining a truly effective factory method, it’s fair to say that the incorporation of the previous “getInstance()” Singleton is a considerable improvement for avoiding issues related to multiple instances.

Well, at this stage I’m pretty sure that you understand the purpose of coding the static “getInstance()” method. However, the missing part here is the lack of an example that shows how to use this method in conjunction with the already familiar “factory()” to create some form element objects.

In the last segment of this tutorial I’m going to code that example, so you can see in action the improved version of the sample “FormElementFactory” class.

Please click on the link that appears below and read the final section. 

{mospagebreak title=The enhanced factory class in action} 

As I promised in the previous section, below I coded a final example that demonstrates how to use the improved version of the “FormElementFactory” class to create a couple of web form element objects. Here’s the example in question:

// 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();

Definitely, the above code fragment looks much better than many of its predecessors. The static call to the “getInstance()” method of the factory class returns Singletons of it, which assures that only one instance of the class will be available across the entire script. The rest of the example remains the same, implying that the “factory()” method is again called dynamically, to spawn a couple of web form element objects.

While this example shows how to build a factory method that uses single instances of its originating class, it has plenty of room for improvement. If you’re anything like me, then it’s possible that you hear inside your head a little voice that whispers over and over again: "why not simply declare this factory method static?" Well, your inner voice is right! But, this process will be covered in detail in the next part of the series.

Meanwhile, feel free to tweak all of the code samples shown in this tutorial, so you can quickly start building your own factory methods with PHP 5.

Final thoughts

That’s all for the moment. In this second installment of the series, I explained how to build an improved version of a factory class that returned Singletons of itself to client code. While this approach permits you to avoid creating multiple instances of the class, the truth is that it can be implemented in a much more efficient manner.

If you closely analyze the definition of the class, then you’ll realize that it’s extremely easily to avoid its instantiation by simply declaring its “factory()” method static. So, in the next article I’m going to explore this solution in depth, in this way going one step further in building factory methods with PHP 5.

Don’t miss the upcoming tutorial!

[gp-comments width="770" linklove="off" ]

antalya escort bayan antalya escort bayan Antalya escort diyarbakir escort