Enterprise Integration Zone is brought to you in partnership with:

Jeune has a fascination for building and solving things. His interests include Algorithms, Development Practices and Software Design. When not immersed in his passions, he spends time experimenting in the kitchen. Jose is a DZone MVB and is not an employee of DZone and has posted 10 posts at DZone. You can read more from them at their website. View Full User Profile

For the Nth Time, the Factory Method: A Simpler Introduction

03.21.2013
| 4495 views |
  • submit to reddit
I don’t know what it is, but it took me a long time to finally wrap my head around the Factory Method.

I always found the tutorials at Google not very helpful. My number one source of information wikipedia featured a very simple example that didn’t seem to drive home the point. Here it is for reference:

class Complex {
     public static Complex fromCartesian(double real, double imaginary) {
         return new Complex(real, imaginary);
     }
 
     public static Complex fromPolar(double modulus, double angle) {
         return new Complex(modulus * cos(angle), modulus * sin(angle));
     }
 
     private Complex(double a, double b) {
         //...
     }
}

The first thing that came to my mind when I saw it was that, what’s stopping me from just instantiating the above like so:

Complex number = new Complex(real, imaginary);

I know for one thing that it was a creational pattern but I never found an opportunity to use or apply it. That day has finally come though.

So when can you use it?

One of the things that spurred me to look back time again at the Factory Method was when I was trying to find a solution to the long lines of code I used creating mock objects for my unit tests. They were so long that they irritated me. I knew something was wrong, I was violating the Single Responsibility Principle.

The solution is to delegate creating the object that was going to be tested, injecting dependencies etc somewhere else. Factory methods let you do that.

An Example

Here’s an example of code where I used a factory method:

public function findByProjectId($pID)
{
   $config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini');
   $config = $config->current()->toArray();
             
   $db = new PDO(
      $config['db']['connection'],
      $config['db']['username'],
      $config['db']['password']
   );
   $db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
 
    $q = $db->prepare('query here');
    $q->execute(
      array(
         // params here
      )
    );      
    return $q->fetch(PDO::FETCH_ASSOC);
}

Lines 3-11 are just repetitive code that you can say are repeated in each DAO method. Instead of doing that, a better solution would be to just delegate these lines somewhere else. That somewhere else is a factory method. Here’s my implementation:

class Dao_Manager
{
   private static $DBH;
     
   public static function getPDO()
   {
      if (is_null(self::$DBH)) {
         $config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini');
     $config = $config->current()->toArray();
             
    $DBH = new PDO(
       $config['db']['connection'],
       $config['db']['username'],
       $config['db']['password']
    );
    $DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
 
    self::$DBH = $DBH;
     }
         
     return self::$DBH;
   }
}

Now we can do away with 8 lines of code and just do this instead:

public function findByProjectId($pID)
{
    $db = Dao_Manager::getPDO();
    $q = $db->prepare('query here');
    $q->execute(
      array(
         // params here
      )
    );      
    return $q->fetch(PDO::FETCH_ASSOC);
}

Now that’s a beauty.



Published at DZone with permission of Jose Asuncion, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)