用于数据库连接的单例工厂:
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');
单例不再真正需要,因为所有方法都可以静态调用......
但数据库类仍然可以被视为单例,因为您的应用程序中只有它们的一个实例。
因此,使用工厂和注册表模式可以产生相同的效果。
可以通过将数据库类设置为单例来替换注册表,然后工厂将如下所示:
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;
}
}
因此,您可以选择将所有数据库对象设置为单例或使用注册表。我个人会选择注册表,因为它可以用来存储任何类型的对象,甚至是那些您不想使类成为单例的对象。
在我看来,设计选择总是受到个人风格的影响。