2013-03-05 109 views
1

我正在查看2009年构建的网站的源代码,它是一个自定义框架。返回实例变量V/s返回直接对象

有什么区别?

<?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 /秒

<?php 
class DbAccess { 


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

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

} 

我有几个定做框架的工作,并设置不同的图案,但在时间库,只见返回实例的方法是通过self::$instance有时,它通过new

直接返回这是一个很好的做法?考虑即将推出的PHP版本。

+1

的首先是尝试[单身人士](http://en.wikipedia.org/wiki/Singleton_pattern)。尽管它不断创建新的实例,但这并不完全正确。第二个本质上是一个糟糕的工厂方法。两者都不可取。看到http://en.wikipedia.org/wiki/Singleton_pattern#Drawbacks – Phil 2013-03-05 06:09:51

+0

是的,完全明白!但是,为什么很多人会遵循第二种模式? – Karma 2013-03-05 06:11:19

回答

5

在谈论OOP时,两者都不是好习惯。像其他人已经指出的第一种方法看起来像试图实现单例模式并失败的人。在面向对象方面单身人士有什么不好?它引入了紧密耦合,隐藏依赖和全局状态。基本上它只是使用the global keyword的一种奇特方式。

现在为您的第二个例子。它具有完全相同的缺点基本上是一样的。

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

现在我可能做的就是类似如下(使用dependency injection):

比方说你有一些类需要访问数据库,你会做类似如下:

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(); 
+0

了解。但是,那么返回self :: $ instance是什么意思?我的意思是,这是早些时候的做法,为什么直到今天仍然继续(尽管以最小化的速度)? – Karma 2013-03-05 11:47:42

+0

因为有些人对于正确的面向对象和可测试性没有很好的理解。 – PeeHaa 2013-03-05 11:50:47

+0

-__-这很有用! 因此,从答案我可以得出结论:使用返回单例实例的getInstance()方法可能不是返回对象的很好做法吗?但是,初始化一个对象是! ? – Karma 2013-03-05 11:55:37

0

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

0

第一个例子看起来像一个singleton的示例,但是,它不包含在典型的if exists封装中。该单是很好的做法,当你只想过要创建的类的一个实例:

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

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

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

+1

“当您只希望创建一个类的实例时,单例是一种很好的练习”。不它不是。它只是'global'关键字的唯一写法。 PHP和OOP中的单例没有地方。 – PeeHaa 2013-03-05 11:05:49

+0

请详细说明。 – Karma 2013-03-05 11:43:58