Вопрос

Каков наилучший метод использования шаблона проектирования Singleton в сочетании с шаблоном фабричного метода в PHP5?Мой самый простой сценарий использования — создание выборочного подключения к базе данных только один раз для каждого типа базы данных.

Это было полезно?

Решение

синглтон-фабрика для подключения к БД:

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
            //...
        }
    }
}

Применение:

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

Синглтоны больше не нужны, поскольку все методы можно вызывать статически...Но классы базы данных по-прежнему можно считать одиночными, поскольку в вашем приложении будет только один их экземпляр.

Таким образом, тот же эффект создается при использовании шаблонов фабрики и реестра.

Реестр можно заменить, сделав классы базы данных одноэлементными, тогда фабрика будет выглядеть так:

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;
    }
}

Таким образом, у вас есть выбор: сделать все ваши объекты БД одноэлементными или использовать реестр.Лично я бы выбрал реестр, потому что его можно использовать для хранения любых типов объектов, даже тех, класс которых не нужно делать одноэлементным.

Выбор дизайна всегда зависит от личного вкуса, я...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top