PHP Static v Singleton类 - ConnectionFactory解释

时间:2012-11-14 15:14:54

标签: php static singleton

我是这个级别的PHP编程的新手,我一直在阅读有关单例和静态类的帖子。我正在编写一个有助于我的数据库连接的类。

我遇到了Jon Raphaelson的以下代码(here):

class ConnectionFactory
{
    private static $factory;
    public static function getFactory()
    {
        if (!self::$factory)
            self::$factory = new ConnectionFactory(...);
        return self::$factory;
    }

    private $db;

    public function getConnection() {
        if (!$this->db)                 // this line was modified due to comment
            $this->db = new PDO(...);       // this line was modified due to comment
        return $db;
    }
}

function getSomething()
{
    $conn = ConnectionFactory::getFactory()->getConnection();
    .
    .
    .
}

好像我找到了我要找的东西,不过我有几个问题。

  1. self::$factory = new ConnectionFactory(...); - 我在这个类中没有看到构造函数。我只是创建这个构造函数并传入db详细信息('dbname','user','pass'等)?
  2. getSomething()函数,我假设意图是将所有实际函数放在ConnectionFactory类中检索数据 - 这就是这个函数在这个类中的原因。否则,我本来希望这个函数在另一个类中。 [编辑]跳过这个问题,我没有看到一个支架。
  3. 当两个用户登录到站点并请求数据库连接(两者都在进行更新等)时会发生什么?这是一个单身人士的问题吗?
  4. 谢谢!

3 个答案:

答案 0 :(得分:2)

这主要是为了扩展我在这个问题上的评论...

更好的“单身”模式是:

class ConnectionFactory {

    protected static $connection;

    public function getConnection() {
        if (!self::$connection) {
            self::$connection = new PDO(...);
        }
        return self::$connection;
    }

}

这家工厂的用户应该期待它的实例,而不是自己调用它:

class Foo {

    protected $connectionFactory;

    public function __construct(ConnectionFactory $factory) {
        $this->connectionFactory = $factory;
    }

    public function somethingThatNeedsAConnection() {
        $connection = $this->connectionFactory->getConnection();
        ...
    }

}

$foo = new Foo(new ConnectionFactory);

这允许Foo在需要时自行获取连接,但也允许您向Foo注入一些替代连接,例如用于测试目的。

作为一种便利措施并减少实例化复杂性,这种模式也很好:

class Foo {

    protected $connectionFactory;

    public function __construct(ConnectionFactory $factory = null) {
        if (!$factory) {
            $factory = new ConnectionFactory;
        }
        $this->connectionFactory = $factory;
    }

    ...

}

这仍然允许注入和覆盖依赖项,但是每次实例化Foo时都不需要注入工厂。

答案 1 :(得分:0)

工厂是一个单身人士,因为你不想要一个以上的工厂。

  1. 您不需要构造函数,您可以为工厂设置getFactory()方法所需的任何状态。 getFactory()函数没有获得连接,因此不要在此处进行任何与连接相关的设置,而不是连接对象本身。工厂“构建实例”的类供您使用,因此您可以使用getConnection()方法设置状态并构造工厂应生成的连接对象。
  2. getSomething()不是ConnectionFactory类中的方法,它只是使用工厂类获取工厂,然后获取连接的示例。
  3. 我个人讨厌在PHP中使用方法链接。 getSomething()中真正发生的是:

    function getSomething()
    {
       $factory = ConnectionFactory::getFactory();
       $conn = $factory->getConnection();
       .
       .
       . 
    }
    

答案 2 :(得分:0)

  1. 为了使用new ClassName()实例化,类不需要显式构造函数。但是,如果该类应该是一个单例(并且在这种情况下看起来像它),那么模式的整个点就是从类的外部进行这样的实例化,这就是为什么我认为应该有一个构造函数声明的private关键字。

  2. get getSomething()是一个“独立”函数,其中包含使用您的类的示例。

  3. 没有。多个用户使用PHP的多个实例处理您的脚本,并且它们之间没有任何共享。