我正在寻找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();
}
}
我曾在几个定制框架和不同模式的库集上工作过,但是,有时,我看到返回实例的方法是通过self::$instance
,有时,它直接通过new
返回
哪一个是好的实践?
在讨论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();
静态函数都返回对象的新实例。第一个示例允许您在将来再次静态引用该实例,尽管它存储在私有静态中,因此只能从该类中的成员(函数)访问它。
第一个示例看起来像一个单例示例,但是,它没有被包装在典型的if exists包装器中。当您只希望创建类的一个实例时,使用单例是一种很好的做法:
public static function getInstance() {
if (!isset(self::$instance))
self::$instance = new DbAccess();
return self::$instance;
}
这样做的方式是,你只能通过一个实例访问这个类(这样你就不会打开多个连接到同一个数据库)。
如果要控制构造函数,则可以遵循第二种模式。可以将构造函数设为私有(这样就只有那个类可以调用构造函数并创建新对象)。这在工厂里很常见。