1

我正在研究建于 2009 年的网站的源代码,它是一个自定义框架。

有什么区别?

<?php
class DbAccess {

    private static $instance;

    /**
     * Returns the instance of the DB Class
     */

    public static function getInstance()
    {
        self::$instance = new DbAccess();
        return self::$instance;
    }
}

V/s

<?php
class DbAccess {


    /**
     * Returns the instance of the DB Class
     */

    public static function getInstance()
    {
        return new DbAccess();
    }

}

我曾研究过几个定制框架和一组具有不同模式的库,但有时我看到返回实例的方法是 via self::$instance,有时它直接返回 vianew

哪个是好习惯?考虑即将发布的 PHP 版本。

4

3 回答 3

5

在谈论 OOP 时,两者都不是好习惯。其他人已经指出的第一种方法看起来像是有人试图实现单例模式但失败了。就 OOP 而言,单例有什么不好。它引入了紧密耦合、隐藏依赖和全局状态。基本上它只是使用关键字global一种奇特方式。

现在为您的第二个示例。它基本上是相同的东西,具有完全相同的缺点。

请注意,这两个示例在每次调用该方法时都会创建一个新的数据库连接。这是...不是最佳的。

现在我要做的是如下(使用依赖注入):

假设您有一些需要数据库访问的类,您可以执行以下操作:

class Foo
{
    private $db;

    public function __construct($db)
    {
        $this->db = $db;
    }

    public function methodWhichNeedsDatabaseAccess()
    {
        // do something with $this->db
    }

}

// or whatever instance for database access you are using
$db = new PDO(dsn);
$foo = new Foo($db);
$foo->methodWhichNeedsDatabaseAccess();
于 2013-03-05T11:23:17.130 回答
0

静态函数都返回对象的新实例。第一个示例允许您将来再次静态引用该实例,尽管它存储在私有静态中,因此只能从该类中的成员(函数)访问。

于 2013-03-05T06:10:29.550 回答
0

第一个示例看起来像一个单例示例,但是,它没有包含在典型的 if exists 包装器中。当您只想创建一个类的实例时,单例是一种很好的做法:

public static function getInstance() {
  if (!isset(self::$instance))
    self::$instance = new DbAccess();
  return self::$instance;
}

它的工作方式是你只能通过那个实例访问这个类(这样你就不会打开到同一个数据库的多个连接)。

如果他们想控制构造函数,他们可能会遵循第二种模式。您可以将构造函数设为私有(以便只有该类可以调用构造函数并创建新对象)。这在工厂中很常见。

于 2013-03-05T06:11:30.587 回答