2009-07-26 60 views
1

爲了我自己的利益,我一直在爲自己的小型框架工作,在學習新東西時不斷回溯代碼。正如你所期望的那樣,我有一個幾乎被其他所有對象使用的Registry對象。與Singleton交互的最有效方式是什麼?

目前,最基本的對象(AFObject)設置有點像這樣

absract class AFObject { 

    var $_registry; 

    function __construct(){ 
     $this->_registry = AFRegistry::getInstance(); 
    } 

} 

所以每一個對象現在將包含一個本地引用到註冊表。所以如果我有一百個實例化的對象,那就是數百個對單例的引用。然而這是或多或少效率總是請參閱註冊表直接像這樣...

class AFRouter extends AFObject { 

    function someMethod($bar){ 
     AFRegistry::$foo = $bar; 
    } 

} 
+2

你應該在php 5中使用public,protected或private來代替var關鍵字。 – 2009-07-26 10:20:02

回答

0

我不認爲你應該想想效率在這種情況下(因爲100次的引用確實是沒有問題的,並且有點過早的優化)。但請考慮一下代碼中最優雅的部分。另外,請考慮是否需要單例(可以將它作爲靜態類實現嗎?)。我可能會選擇使用第二種情況,因爲這會讓你的代碼更加明顯(至少我是這麼認爲的)。

在這種情況下,將

class AFRouter extends AFObject { 

    function someMethod($bar){ 
     AFRegistry::getInstance()->$foo = $bar; 
    } 

} 

或者,如果你封裝你的財產:

class AFRouter extends AFObject { 

    function someMethod($bar){ 
     AFRegistry::getInstance()->setFoo($bar); 
    } 

} 
2

在我看來, 「註冊表」 類型的類種smells的。

既然你提到你是爲了學習和變得更好,你有沒有考慮徹底根除你的註冊表類並採取另一種方法?也許將所需的數據推送給類構造函數,而不是將其從類內部拉出來?

我要離開了選項1(抽象基類),因爲那時所有的類都變得依賴於一些其他類...

使用靜態類像Yngve Sneen提到的將是最好的辦法我意見如果你想保持註冊表設置。

類似於: registry :: set('var1',$ var1); $ var1 = registry :: get('var1');

1

考慮一下:

class AFRouter extends AFObject { 
    function someMethod($bar) { 
    global $af_registry; 
    $af_registry->setFoo($bar); 
    } 
} 

甚至:

class AFRouter extends AFObject { 
    function someMethod($bar) { 
    af_registry_set('foo', $bar); 
    } 
} 

酒吧語法,有本質上,這和當前的解決方案沒有任何區別。

是的,這意味着您的註冊表本質上是一個全局變量。是的,全局變量存在問題。更好的選擇是pass in the dependencies

相關問題