对象A的单个实例的值由对象B的许多实例使用

时间:2013-01-25 17:02:22

标签: php oop

我整天都在研究这个问题,但我还没有找到一个好的解决方案。

在我们开始之前:如果你认为答案是“单身人士”,那就不是,单身人士不允许进入项目。不要问我为什么,因为我不想再讨论这个问题了。 :)

所以这里(这只是一个例子):

  • A类的对象X(只允许存在一个实例,但需要创建它)
  • 对象X具有某种属性,例如 $ color ='green';
  • 创建的B类的所有对象都获得该属性的值。
  • 当对象X的属性更改为 $ color ='red'; 创建的B类的所有新对象将获得新值
  • 如果在A类之一尚未存在时创建B类对象,则需要创建A类对象

现在的问题是......如何构建我的类,并确保只创建了一个A类实例?

我有道理吗?

4 个答案:

答案 0 :(得分:1)

您可以将X的第一个创建实例保留在X类的静态属性中,如下所示:

class X {
  static public $instance = null;
  public function __construct() {
    if (is_null(X::$instance)) {
      X::$instance = $this;
    }
    ...
  }
}

然后,您可以在X::$instance->color构造函数中引用B::__construct()

更好的方法可能是拥有B工厂,将X实例注入其中,让B类期望X实例作为构造函数参数:

class BFactory {
  protected $x;
  public function __construct($x) {
    $this->x = $x;
  }
  public function make_instance() {
    return new B($this->x);
  }
}
$factory = new BFactory($X);
$instance = $factory->make_instance();

答案 1 :(得分:1)

我不太清楚你的申请的目的是什么。不过,您可以使用静态变量来跟踪对象。

class A
{
    private static $instance_exists = false;
    private static $color = 'green';

    public function __construct() {
        if(self::$instance_exists) {
            throw new Exception('tried to create another instance of A');
        }
        self::$instance_exists = true;
    }

    public static function getColor() {
        return self::$color;
    }

    public static function instanceExists() {
        return self::$instance_exists;
    }

}

class B {
    private $color;

    public function __construct() {
        $this->color = A::getColor();
    }
}

A::instanceExists(); // check anywhere

答案 2 :(得分:0)

在对象X上创建一种属性更改侦听器。

  • 如果color属性已更改,则每个对象B向对象X注册以接收通知。这可以在对象B构造函数中完成。
  • 在属性更改事件中,对象X调用“set属性”,就像它保留在某个内部集合中的所有对象B的方法一样。
  • 对象X在逻辑上存储在最初可能为null的某个引用中。如果为null,则对象B可以在其构造函数中创建新对象。
  • 如果对象B想要主动更改全局颜色属性,则需要保留对象A的内部引用。必须做一些事情以防止无限循环的通知事件(传递事件源(对象B,将颜色改变为对象X以及颜色值等)。

不幸的是,当创建B的新实例时,它必须从某处获得有关可能存在的X的引用。如果这不是一个全局静态字段,可能是:

  • 让我们假设像细菌这样的物体B只能相互衍生,所以它们可以通过内部非静态参考。必须以某种特殊方式创建第一个实例。
  • 假设我们在某个方法/函数中创建所有对象B,我们可以使用局部变量来保存X引用。

答案 3 :(得分:0)

在一些很酷的家伙和dudettes的帮助下。 :)

这是一个优雅的解决方案,并不是我想到的,但它确实有效。请注意,这仅仅是一个例子,还有更多的内容。

class A {
    public $color;
    function __construct($new_color) {$this->color = $new_color;}
}

class B extends A {}

$color = 'green';
$y[0] = new B($color);
$y[1] = new B($color);
$color = 'red';
$y[2] = new B($color);
$color = 'black';
$y[3] = new B($color);

感谢大家的意见和建议。它帮助了我们很多。谢谢......