0

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

在我们开始之前:如果您认为答案是“单例”,那不是,项目中不允许使用单例。不要问我为什么,因为我不想再参加那个讨论了。:)

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

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

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

我说得有道理吗?

4

4 回答 4

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();
于 2013-01-25T17:10:51.167 回答
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
于 2013-01-25T17:15:39.307 回答
0

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

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

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

  • 让我们假设像细菌这样的对象 B 只能从另一个派生,因此它们可以传递内部非静态引用。第一个实例必须以某种特殊方式创建。
  • 假设我们在某个方法/函数中创建所有对象 B,我们可以在其中使用局部变量来保存 X 引用。
于 2013-01-25T17:12:24.297 回答
0

在一些很酷的帅哥和帅哥的帮助下。:)

这是一个优雅的解决方案,与我的想法不太一样,但它确实有效。请注意,这只是一个示例,引擎盖下还有更多内容。

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);

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

于 2013-01-26T11:00:14.677 回答