Difference between singleton and factory pattern

Posted on September 2, 2017 by Suresh Kamrushi in PHP

##Singleton

The single pattern is an often used pattern in many applications when only a single instance of a resource is required. The most obvious type of resource for PHP web pages is a database connection, although other resource types can be used. When fetching of dynamically creating a web page several database calls may need to be made. If a single instance of the resource could be used, rather than creating several connections, the overhead is minimized. The single instance in this case, is created by the singleton pattern.

<?php
class db {
    /*** Declare instance ***/
    private static $instance = NULL;

    /**
     * the constructor is set to private so
     * so nobody can create a new instance using new
     */
    private function __construct() {
        /*** maybe set the db name here later ***/
    }

    /**
     * Return DB instance or create intitial connection
     *  @return object (PDO)
     * @access public
     */
    public static function getInstance() {
        if (!self::$instance) {
            self::$instance = new PDO("mysql:host='localhost';dbname='animals'", 'username', 'password');
            self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        }
        return self::$instance;
    }
    /**
     * Like the constructor, we make __clone private
     * so nobody can clone the instance
     */
    private function __clone() {

    }
} /*** end of class ***/
?>

Lets look at what has happened in the singleton class above. A variable name `$instance` is created and made `private`, this ensures nobody and try to access it directly. Similarly, the constructor and __clone methods have been made private to prevent cloning of the class, or of somebody trying to instantiate an instance of it. The class has a single method for providing a resource, the `getInstance()` method.

The `getInstance()` method checks that an instance does not already exist. If no instance exists a new instance of the PDO class is created and assigned to the `$instance` variable. If an existing instance is available, the `getInstance()` method returns this. The result is that the returned value is always the same instance, and no new resource, or overhead, is required.

Here is a small demonstration of how this might be used in an application.

<?php
try {
    /*** query the database ***/
    $result = DB::getInstance()->query("SELECT animal_type, animal_name FROM animals");

    /*** loop over the results ***/
    foreach ($result as $row) {
        print $row['animal_type'] .' - '. $row['animal_name'] . '<br />';
    }
} catch (PDOException $e) {
    echo $e->getMessage();
}
?>

##Factory

The factory pattern is a class that creates objects for you, rather than you needing to use the new keyword to create one yourself. The factory is, as the name suggests, a factory for creating objects. Why do we need this? Lets consider an application that uses an `ini` file for configuration option. Then the application is changed to gain the configuration options from a database. The rest of the application falls apart like a house of cards as the base is removed.
This “*tight coupling*” of objects, where each object relies heavily on another, creates problems in larger applications. A system is needed where objects can reference each other, but are not inter dependent.
In our example of the configuration file becoming a database, if other classes were dependent on the class that read from the `ini` file, and this was suddenly tasked to the database class problems occur.
By using the factory design pattern, if you change the type of object from the `ini` reader class to the database class you only need to change the factory. Any other code that uses the factory will be updated automatically.

<?php
/**
 * @config interface
 */
interface Config {
    function getName();
}

/**
 * @config class
 */
class userConfig implements Config {
    /*
     * @username
     */
     public $user_id;

     /*** contructor is empty ***/
     public function __construct($id) {
        $this->user_id = $id;
     }

     public static function Load($id) {
        return new userConfig($id);
     }

     public function getName() {
         try {
             /*** query the database ***/
             $sql = "SELECT username FROM user_table WHERE user_id=:user_id";
             $db = db::getInstance();
             $stmt = $db->prepare($sql)
             $stmt->bindParam(':user_id', $this->user_id, PDO::PARAM_INT);
             return $stmt->fetch(PDO::FETCH_COLUMN);    
        } catch (PDOException $e) {
            /*** handle exception here ***/
            return false;
        }
    }
} /*** end of class ***/

/*** returns instance of config ***/
$conf = userConfig::Load( 1 );
echo $conf->getName();
?> 

This might seem a little excessive code for simply retrieving a username. But in large-scale application where a change from file based to database retrieval is made, the results could be catastrophic. Here its is simply a matter of changing the the `getName()` method retrieves the name, and the returned object is the same, thus allowing other parts of the application that require the username, eg: a login for a cart, to continue as they did previously.

Tagged as ,