The Basics of Using the Factory Pattern in PHP 5

If you need to create multiple objects that belong to the same family, you probably want to use the factory pattern. This three-part series takes a close look at using the factory pattern in PHP.

Introduction

Many PHP developers with a solid background in pattern-based programming know that there are certain patterns that are more difficult to grasp than others. This is due mostly to the inherent diversity of this fascinating terrain, where purist concepts about software design merge flawlessly with simple, natural common sense.

Indeed, design patterns present singularly interesting facets. They are conceived as proven solutions to specific programming-related issues, but at the same time, have a certain dose of improvisation, which makes them even more attractive. Logically, if you think carefully about this concept, you’ll understand more clearly the meaning of this question: how many times did you find yourself applying a particular pattern without knowing what you were actually doing? Perhaps dozens, even hundreds of times.

Nevertheless, the most important thing to notice here is that a concrete problem can be solved by implementing the logic of a particular pattern, which means that certain software development issues can be addressed in a more intuitive way than others. And definitely, the factory pattern is an excellent example of this situation, since many developers use it frequently, even if they’re taking their first steps into the object-oriented programming arena.

Admittedly, it’s common to see during the development of a given PHP application that one or more classes are created with the purpose of returning a specific type of object to client code, where the object must conform to the specifications of a concrete environment. As you may have guessed, this is precisely the theoretical definition of the factory pattern.

Summarizing, the factory pattern can be really useful when it comes to creating multiple objects that belong to the same family. In this three-part series I’m going to take a close look at it, and also demonstrate its remarkable functionality by showing you a decent variety of code samples, so you can start quickly including this pattern into your own PHP applications.

With the preliminaries out of the way, now let’s move on together and begin discovering how to apply the factory pattern with PHP. It’s going to be an educational journey, believe me!

{mospagebreak title=Developing some basic factory classes}

To start demonstrating the neat functionality provided by the factory pattern, I’ll define a few basic factory classes whose primary task will consist of returning different types of array objects to client code according to the concrete specifications of a given programming environment.

As you’ll see, these concrete factories will be capable of "factoring" array objects that will work with both numeric and associative indexes. But let’s get away from theory for a moment and see how these brand new factory classes look. Their respective signatures are as follows:

// define abstract ‘ArrayFactory’ class
abstract class ArrayFactory{
  
abstract public function createArrayObj($type);
}

// define concrete factory to create numerically-indexed array
objects
class NumericArrayFactory extends ArrayFactory{
  
private $context=’numeric';
  
public function createArrayObj($type){
    
$arrayObj=NULL;
    
switch($type){
      
case "uppercase";
        
$arrayObj=new UppercasedNumericArrayObj();
         
break;
      
case "lowercase";
        
$arrayObj=new LowercasedNumericArrayObj();
        
break;
      
default:
        
$arrayObj=new LowercasedNumericArrayObj();
         
break; 
     
}
     
return $arrayObj;
   
}
}

// define concrete factory to create associative array objects
class AssociativeArrayFactory extends ArrayFactory{
  
private $context=’associative';
  
public function createArrayObj($type){
    
$arrayObj=NULL;
    
switch($type){
      
case "uppercase";
        
$arrayObj=new UppercasedAssociativeArrayObj();
        
break;
      
case "lowercase";
        
$arrayObj=new LowercasedAssociativeArrayObj();
        
break;
      
default:
        
$arrayObj=new LowercasedAssociativeArrayObj();
        
break; 
     
}
    
return $arrayObj;
   
}
}

As demonstrated above, the previous concrete factory classes (excepting logically the first one, which has been declared abstract) implement the required business logic to create different types of array objects in accordance with the specifications of a given environment.

In consonance with the previous concept, the first factory class, which is called "NumericArrayFactory," is responsible for spawning three different types of numeric array objects.  All of them are obviously conceived to work in a "numeric" context.

Now, concerning the definition of the second concrete factory, you can see that this one returns only associative array objects to client code, which logically must conform to the specifications of an "associative" environment.

Undeniably, after studying the respective signatures of the two previous factory classes, you’ll realize that implementing the factory pattern with PHP is actually an easy-to-grasp process that can be performed with minor hassles.

So far, so good, right? At this stage I demonstrated how to build a couple of concrete factory classes that are tasked with spawning different types of array objects. So what’s the next step? Well, as you learned before, these array objects obviously are spawned from a bunch of concrete classes, so in the following section I’m going to show you their respective signatures. You’ll see more easily how the different classes used to implement the factory pattern are linked with each other.

To learn how these array-related classes will be defined, please click on the link below and keep reading.

{mospagebreak title=Defining some array processing classes}

As you’ll certainly recall from the prior section, the two concrete factory classes defined in that part of the article were responsible for creating distinct types of array-processing objects, where each of them is backed up by an originating class.

Therefore, in the new few lines I’m going to list the complete definitions for all of these array handling classes, so you can have a better idea of how they look and work.

Here are the signatures for these classes:

// define abstract ‘ArrayObj’ class
abstract class ArrayObj{
  
abstract public function getArraySize();
   abstract public function getArrayElements();
}

// define concrete ‘UppercasedNumericArrayObj’ class
class UppercasedNumericArrayObj extends ArrayObj{
  
private $inputArray=array(‘Element 1′,’Element 2′,’Element
3′);
  
public function getArraySize(){
    
return count($this->inputArray);
  
}
  
public function getArrayElements(){
    
return array_map(strtoupper,$this->inputArray);
  
}
}

// define concrete ‘LowercasedNumericArrayObj’ class
class LowercasedNumericArrayObj extends ArrayObj{
  
private $inputArray=array(‘ELEMENT 1′,’ELEMENT 2′,’ELEMENT
3′);
  
public function getArraySize(){
    
return count($this->inputArray);
  
}
  
public function getArrayElements(){
    
return array_map(strtolower,$this->inputArray);
  
}
}

// define concrete ‘UppercasedAssociativecArrayObj’ class
class UppercasedAssociativeArrayObj extends ArrayObj{
  
private $inputArray=array(‘Element 1’=>’This is element
1′,’Element 2’=>’This is element 2′,’Element 3’=>’This is element
3′);
  
public function getArraySize(){
    
return count($this->inputArray);
  
}
  
public function getArrayElements(){
    
return array_map(strtoupper,$this->inputArray);
  
}
}

// define concrete ‘LowercasedAssociativecArrayObj’ class
class LowercasedAssociativeArrayObj extends ArrayObj{
  
private $inputArray=array(‘ELEMENT 1’=>’THIS IS ELEMENT
1′,’ELEMENT 2’=>’THIS IS ELEMENT 2′,’ELEMENT 3’=>’THIS IS ELEMENT
3′);
  
public function getArraySize(){
    
return count($this->inputArray);
  
}
  
public function getArrayElements(){
    
return array_map(strtolower,$this->inputArray);
  
}
}

As you can see, the group of array processing array classes listed above presents two methods, named "getArraySize()" and "getArrayElements()" respectively, which are common to all of them. However, regardless of the simple logic implemented by these classes, you should notice that the first pair is defined to work in a "numeric" context, while the other two are conceived for use in a "associative" environment.

Here, it’s clear to see how the factory pattern works in a nutshell, since the two factory classes defined in the previous section must return only array processing objects that conform a set of predefined rules to calling code. Now are you starting to grasp the logic that stands behinds the factory pattern? I bet you are!

All right, having analyzed in detail how all the array handling classes previously created work, it’s a good time to develop an example in which all these classes will be put to work in tandem. As you may have guessed, the reason to code this practical example is simply to demonstrate the functionality provided by the pair of factory classes that you learned before.

Want to see how this example will be set up? Read the following section. I’ll be there, waiting for you.

{mospagebreak title=Testing the functionality of the factory pattern}

In consonance with the concepts deployed in the previous section, my intention here is to illustrate how the factory pattern functions. Below I listed the definition of a simple script that shows how to use the two factory classes defined earlier to create a bunch of array processing objects. Also, it should be noticed that the factories’ methods are called statically via the scope resolution operator (::), so no instances of them are required.

That being said, here is the testing script in question:

try{
  
// create lowercased numeric array object
  
$lowerNumArray=NumericArrayFactory::createArrayObj
(‘lowercase’);
  
// display array object size
  
echo ‘Number of elements of lowercased numeric array is the
following : ‘.$lowerNumArray->getArraySize();

   /*
  
displays the following:
  
Number of elements of lowercased numeric array is the
following : 3
  
*/

   // display array object elements
  
print_r($lowerNumArray->getArrayElements());

   /*
  
displays the following
  
Array ( [0] => element 1 [1] => element 2 [2] => element 3 )
  
*/

   // create uppercased numeric array object
  
$upperNumArray=NumericArrayFactory::createArrayObj
(‘uppercase’);
  
// display array object size
  
echo ‘Number of elements of uppercased numeric array is the
following : ‘.$upperNumArray->getArraySize();

   /*
  
displays the following:
  
Number of elements of uppercased numeric array is the
following : 3
  
*/

   // display array object elements
  
print_r($upperNumArray->getArrayElements());

   /*
  
displays the following
  
Array ( [0] => ELEMENT 1 [1] => ELEMENT 2 [2] => ELEMENT 3 )
  
*/

   // create lowercased associative array object
  
$lowerAssocArray=AssociativeArrayFactory::createArrayObj
(‘lowercase’);
  
// display array object size
  
echo ‘Number of elements of lowercased associative array is
the following : ‘.$lowerAssocArray->getArraySize();

   /*
  
displays the following:
  
Number of elements of lowercased associative array is the
following : 3
  
*/

   // display array object elements
  
print_r($lowerAssocArray->getArrayElements());

   /*
  
displays the following
  
Array ( [ELEMENT 1] => this is element 1 [ELEMENT 2] => this
is element 2 [ELEMENT 3] => this is element 3 )
  
*/

   // create uppercased associative array object
  
$upperAssocArray=AssociativeArrayFactory::createArrayObj
(‘uppercase’);
  
// display array object size
  
echo ‘Number of elements of uppercased associative array is
the following : ‘.$upperAssocArray->getArraySize();

   /*
  
displays the following:
  
Number of elements of uppercased associative array is the
following : 3
  
*/

   // display array object elements
  
print_r($upperAssocArray->getArrayElements());

   /*
  
displays the following
  
Array ( [Element 1] => THIS IS ELEMENT 1 [Element 2] => THIS
IS ELEMENT 2 [Element 3] => THIS IS ELEMENT 3 )
  
*/
}

catch(Exception $e){
  
echo $e->getMessage();
  
exit();
}

Do you see how easy it was to spawn different array processing objects using statically the corresponding factory classes? Definitely, this is a clear and simple demonstration of how the factory pattern can be implemented with PHP 5.

However, the prior example shouldn’t stop you from developing your own testing scripts. Doing so will give you a better understanding of the remarkable functionality offered by this design pattern in particular.

Final thoughts

In this first installment of the series, I introduced the key points of how to implement the factory pattern with PHP 5. Nevertheless, this educational journey has just begun, since in the next part of the series I’m going to teach you how to use this pattern in a more useful fashion, more specifically to work with file and cookie-processing classes.

Now that you know what the next article will be about, I hope to see you there!

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

chat sex hikayeleri Ensest hikaye