The Factory Pattern: OOP Techniques in PHP

Posted on 02. Mar, 2009 by Will Fitch in PHP

The purpose of the factory pattern is to assist with maintaining loose coupling. Code that is tightly coupled is error prone in that if a class is changed, it can have a domino affect to other scripts using it. This is typical to large-scale systems and smaller systems that grow very fast.

For example, let’s assume you have a relatively small system that contains a class called Users. This class reads user data from a small file located on disk. Your system booms, and you need to move to a RDBMS (Relational Database Management System). Because of this, your methods in the class, data source and other items change, breaking the code that is utilizing the Users class. This is where the factory pattern comes in.

The factory pattern’s purpose is to contain methods that create objects for you. Instead of directly instantiating the Users class, you request an instance from a factory class (we’ll call it UsersFactory), and call a static method (we’ll call it getInstance).

Example

PHP
  1. <?php
  2. class Users
  3. {
  4.         private $_userId;
  5.         public function getUserById()
  6.         {
  7.                 // go get a user
  8.         }
  9.        
  10.         public function __construct($id)
  11.         {
  12.                 $this->_userId = $id;
  13.         }
  14. }
  15.  
  16. class UsersFactory
  17. {
  18.         public static function getInstance($id)
  19.         {
  20.                 return new Users($id);
  21.         }
  22. }
  23.  
  24. $user = UsersFactory::getInstance($id);
  25. ?>

The example above demonstrates how a factory method would work. Now, let’s add in that new class that gets the users from the database. Let’s assume you have 25 other scripts that use the existing class. You can create the new Users_From_DB class and create a static method to reference that as well.

PHP
  1. <?php
  2.  
  3. class Users
  4. {
  5.         private $_userId;
  6.         public function getUserById()
  7.         {
  8.                 // go get a user
  9.         }
  10.        
  11.         public function __construct($id)
  12.         {
  13.                 $this->_userId = $id;
  14.         }
  15. }
  16.  
  17. class Users_From_DB
  18. {
  19.         // same class only from db
  20. }
  21.  
  22. class UsersFactory
  23. {
  24.         public static function getInstance($id)
  25.         {
  26.                 return new Users($id);
  27.         }
  28.        
  29.         public static function getUsersFromDB($id)
  30.         {
  31.                 return new Users_From_DB($id);
  32.         }
  33. }
  34. ?>

This allows you to maintain a loose coupling with a class that could create major problems in the event it goes through major changes.

Conclusion

I have seen where some use the factory pattern as a singleton. They look similar but serve two very different purposes. Take the code below:

PHP
  1. <?php
  2.  
  3. class Users_Model
  4. {
  5.         public function getUserById($id)
  6.         {
  7.                 // do something
  8.         }
  9. }
  10.  
  11. class Model
  12. {
  13.         private static $instances=array();
  14.        
  15.         public static function factory($model_name)
  16.         {
  17.                 if (array_key_exists($model_name, self::$instances))
  18.                 {
  19.                         return self::$instances[$model_name];
  20.                 }
  21.                 return self::$instances[$model_name] = new $model_name();
  22.         }
  23. }
  24.  
  25. $model = Model::factory(‘Users_Model’);
  26. $model2 = Model::factory(‘Users_Model’);
  27. ?>

While the case could be made that it is acting as a factory pattern, it is being used more as a singleton, maintaining a single instance of a class.

The factory pattern does a really good job, and like the singleton, it serves a very specific purpose.

Tags: , , ,

Related Articles

Leave a Reply