2010-04-06 77 views
5

我用來創建一個單獨的類像這樣的實例:擴展單個類

$Singleton = SingletonClassName::GetInstance(); 

和非單例類:

$NonSingleton = new NonSingletonClassName; 

我認爲我們不應該區分我們如何創造一個類的實例是否是單例。如果我看着其他班級的感知,我不在乎班級是否需要單身班。所以,我仍然不熟悉php如何對待單身課程。我想,我總是想寫:

$Singleton = new SingletonClassName; 

只是另一個非單身類,有沒有解決這個問題?

+1

Tthis不是問題 - 你抱怨說你不喜歡一個模式是如何完成的。 -1 – 2010-04-06 12:57:06

+1

這是一個非常合理的問題。 +1,因爲-1不是:P – Leo 2010-04-06 12:59:06

+2

不要使用PHP? – Kevin 2010-04-06 12:59:36

回答

2

我不會推薦它,因爲它會使你的代碼更加難於理解(人們認爲新指一個全新的對象)。但是,我不會重新使用單身人士。

此代碼的基本思想是圍繞單例包裝。通過該包裝器訪問的所有函數和變量實際上都會影響單例。如下面的代碼沒有實現很多的魔術方法和SPL的接口,但它們可以根據需要

代碼

/** 
* Superclass for a wrapper around a singleton implementation 
* 
* This class provides all the required functionality and avoids having to copy and 
* paste code for multiple singletons. 
*/ 
class SingletonWrapper{ 
    private $_instance; 
    /** 
    * Ensures only derived classes can be constructed 
    * 
    * @param string $c The name of the singleton implementation class 
    */ 
    protected function __construct($c){ 
     $this->_instance = &call_user_func(array($c, 'getInstance')); 
    } 
    public function __call($name, $args){ 
     call_user_func_array(array($this->_instance, $name), $args); 
    } 
    public function __get($name){ 
     return $this->_instance->{$name}; 
    } 
    public function __set($name, $value){ 
     $this->_instance->{$name} = $value; 
    } 
} 

/** 
* A test singleton implementation. This shouldn't be constructed and getInstance shouldn't 
* be used except by the MySingleton wrapper class. 
*/ 
class MySingletonImpl{ 
    private static $instance = null; 
    public function &getInstance(){ 
     if (self::$instance === null){ 
      self::$instance = new self(); 
     } 
     return self::$instance; 
    } 

    //test functions 
    public $foo = 1; 
    public function bar(){ 
     static $var = 1; 
     echo $var++; 
    } 
} 

/** 
* A wrapper around the MySingletonImpl class 
*/ 
class MySingleton extends SingletonWrapper{ 
    public function __construct(){ 
     parent::__construct('MySingletonImpl'); 
    } 
} 

例子

$s1 = new MySingleton(); 
echo $s1->foo; //1 
$s1->foo = 2; 

$s2 = new MySingleton(); 
echo $s2->foo; //2 

$s1->bar(); //1 
$s2->bar(); //2 
中添加它不是完美的
+0

哇,這很酷。非常感謝你 ! – cakyus 2010-04-08 10:08:35

3

它最好是周圍的其他方式 - 提供非單身一factory-method,並使用獲得它們的實例:

$NonSingleton = NonSingletonClassName::createInstance(); 

這是對Java(在Effective Java)建議的最佳實踐,但它適用到大多數面向對象的語言。

1

不能像常規類實例一樣創建Singleton。 new將始終返回一個新的實例,因此您必須使構造函數非公共,因此您必須有不同的方法從類中調用它。

您可以在所有類上都有工廠方法,例如總是做getInstance()像在另一個答案中所示。另一種選擇是使用知道是否返回什麼的Service LocatorDependency Injection Framework

1

根據什麼new關鍵字意味着所有你想要的是無關緊要的。 new創建新的類實例,這就是爲什麼它命名爲 :-)

+0

哈哈..你是絕對正確的:-) – cakyus 2010-04-08 10:17:17