Singleton in Conjunction with the Factory Pattern in PHP5


Question

What is the best method for using singleton design pattern in conjunction with the factory method pattern in PHP5? My simplest usage scenario for this is instantiation selective database connection only once for each database type.

1
4
12/24/2012 9:25:21 PM

Accepted Answer

singleton factory for DB connection:

class Registry
{
    private static $_objects;

    public static function set($key, $object)
    {
        if (!array_key_exists($key, self::$_objects)) self::$_objects[$key] = $object;
    }

    public static function get($key)
    {
        if (array_key_exists($key, self::$_objects)) return self::$_objects[$key];
        else return false;
    }
}

class DBFactory
{
    public static function getConnection($type)
    {
        switch ($type) {
            case 'pdo':
                if (!(Registry::get('DB_PDO') instaceof DbPdo)) Registry::set('DB_PDO', new DbPdo('user', 'pass', ...));
                return Registry::get('DB_PDO')
            case 'mssql':
                //same for other connections
            //...
        }
    }
}

usage:

$factory = DBFactory::getConnection('pdo');

Singletons are not really needed anymore because all methods can be called statically... But the database classes can still be considered singletons because there will only be one single instance of them in your application.

So the same effect is created by using the factory and registry patterns.

The registry could be replaced by making your database classes singletons then the factory would look like this:

class DBFactory
{
    public static function getConnection($type)
    {
        switch ($type) {
            case 'pdo':
                return DbPdo::getInstance('user', 'pass', ...);
            case 'mssql':
                //same for other connections
            //...
        }
    }
}

class DbPdo
{
    private static $_instance;

    private function __construct($user, $pass, ...){ //instantiate object }

    public static function getInstance($user = null, $pass = null, ...)
    {
        if (!(self::$_instance instanceof DbPdo)) self::$_instance = new DbPdo($user, $pass, ...);
        return self::$_instance;
    }
}

So you have the choice of making all your DB objects singletons or using a registry. I personally would go with a registry because it can be used to store any types of object, even the ones where you don't want to make the class a singleton.

Design choices are always subjected to personal flavor imo...

10
1/14/2015 2:50:01 PM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon