2个单身类可以相互引用吗?

时间:2011-02-04 21:58:24

标签: php oop singleton

为什么这不起作用?每个实例不应该只引用一次吗?

class foo {
    private static $instance;
    private function __construct() {
    $test = bar::get_instance();
    }

    public static function get_instance() {
        if (empty(self::$instance)) {
            self::$instance = new foo();
        }
        return self::$instance;
    }
}

class bar {
    private static $instance;
    public function __construct() {
    $test = foo::get_instance();
    }

    public static function get_instance() {
        if (empty(self::$instance)) {
            self::$instance = new bar();
        }
        return self::$instance;
    }
}

$test = foo::get_instance();

4 个答案:

答案 0 :(得分:4)

你拥有所谓的circular-dependency。 A需要B来完成构建,而B需要A来完成构建。所以它永远是圆形的。

基本上,正在发生的事情是,在self::$instance完成之前,每个类的new class()都不会被填充。所以在构造函数中,你正在调用另一个getInstance。但每次点击get_instance()时,self::$instance仍然为空,因为之前的new从未过滤过。你走了一圈又一圈。它会一直持续到最后。

相反,在构造之后添加它:

class foo {
    private static $instance;
    private function __construct() {
    }
    private function setBar(bar $bar) {
        $this->bar = $bar;
    }

    public static function get_instance() {
        if (empty(self::$instance)) {
            self::$instance = new foo();
            self::$instance->setBar(bar::get_instance());
        }
        return self::$instance;
    }
}

class bar {
    private static $instance;
    public function __construct() {
    }
    private function setFoo(foo $foo) {
        $this->foo = $foo;
    }
    public static function get_instance() {
        if (empty(self::$instance)) {
            self::$instance = new bar();
            self::$instance->setFoo(foo::get_instance());
        }
        return self::$instance;
    }
}

但是,我会真的建议重新设计你的人际关系和课程,以便你Inject the Dependencies而不是自我依赖的单身人士。

答案 1 :(得分:3)

您将获得无限递归:

FOO :: get_instance(); - > foo构造函数 - > bar :: get_instance() - > bar constructur - > FOO :: get_instance(); - > ...

答案 2 :(得分:0)

因为两个构造函数都没有返回。无法创建foobar实例,因为它们会相互引用。

答案 3 :(得分:0)

这里有一个递归的例子。调用堆栈如下所示:

foo::get_instance() 
foo::__construct()
bar::get_instance()
bar::__construct()
foo::get_instance()
foo::__construct()
...

发生这种情况的原因是,当从bar构造函数调用foo :: get_Instance时,它仍处于对foo::get_Instance的初始调用的上下文中,并且尚未设置$instance

有很多方法可以解决这个问题,但我首先会问你为什么需要将它们作为彼此的成员。

如果您不需要,只需在需要访问它们的位置拨打foo::get_instancebar::get_instance