2010-05-22 79 views
0

我目前遇到無窮遞歸情況。解決php無窮遞歸問題

我執行調用各種對象的方法,消息服務..它是相當相似的觀察者模式..

這是怎麼回事什麼:

Dispatcher.php

class Dispatcher { 
... 
    public function message($name, $method) { 

    // Find the object based on the name 
    $object = $this->findObjectByName($name); 

    if(!$object->decorations)) 
      // Decorate the object 
     $object = new $name($object); // This is where it locks up. 
      $object->decorations = true; 
    } 

    return $object->$method(); 
... 
} 

class A { 
    function __construct() 
    { 
     $Dispatcher->message("B", "getName"); 
    } 

    public function getName() { 
     return "Class A"; 
    } 

} 

class B { 
    function __construct() 
    { 
      // Assume $Dispatcher is the classes 
     $Dispatcher->message("A", "getName"); 
    } 

    public function getName() { 
     return "Class B"; 
    } 

} 

兩個對象均未初始化時鎖定。它只是從消息中來回傳遞,沒有人可以初始化。

我正在尋找某種隊列實現,它將使消息等待對方。返回值仍然設置的位置之一。我希望儘可能在A類和B類中使用盡可能少的樣板代碼。


我得到了很多談not_initialized方法的,不幸的是我覺得這個討論在錯誤的方向去。這是我的錯,我會再解釋一下情況(我希望更好)。

$object實現裝飾圖案 - 這是$object得到更多的功能(方法),當我初始化A類和B類,我需要使用從消息傳遞方法裝飾提供這些功能,這就是爲什麼如果沒有裝飾,裝飾它。我真的不認爲not_initialized會成爲問題,因爲當說$objectA被選中時,它尚未裝飾 - 所以我想將這些方法添加到它。類A和B是裝飾類。所以not_initialized在當時是正確的。當我嘗試裝飾物體時,它會卡住。我改變了代碼以更好地反映這種情況。

+0

請提供'Dispatcher :: not_initialized()'的代碼,因爲那是產生錯誤的代碼,因爲它不能正確記住哪些對象已經被初始化。 – jigfox 2010-05-22 11:41:58

+0

另外,'findObjectByName'在做什麼?我不確定你想在這裏實現什麼。你是否試圖用A和B類來裝飾單個對象? – Thorarin 2010-05-22 15:41:57

回答

4

這不是死鎖的例子,而是無盡的遞歸。很可能你的not_initialized函數返回true,直到構造函數完全運行。 因此,構造A類型的對象將間接調用B構造函數,該構造函數將調用A構造函數,並且無限地進行調用。

您必須更改not_initialized函數,或者如果可以,將消息從構造函數中移出。

Deadlock是涉及多個進程的情況。在這種情況下,只有一個過程。

+0

噢好吧,無盡的遞歸更有意義。當我嘗試構建它時,它鎖定了。不幸的是,我無法將信息從構造函數中移出(我嘗試過 - 它只是推遲了一大堆問題)。我想知道是否有任何隊列實現可以解決這個問題... – Matt 2010-05-22 11:29:05

+0

您不需要隊列,但是您必須更改hte'not_initialized'方法,以便它能夠正確記住哪個對象已初始化。 – jigfox 2010-05-22 11:43:24