2010-05-22 83 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