0

I have been researching this all day, and I haven't found a good solution yet.

Before we get started: if you think the answer is "singleton", it isn't, singletons are not allowed in the project. Don't ask me why, cause I do not want to go in that discussion again. :)

So here goes (it is just an example):

  • Object X of class A (only one instance is allowed to exist, but it needs to be created)
  • Object X has a certain property like $color = 'green';
  • All objects of class B that are created get the value of that property.
  • When the property of Object X changes to $color = 'red'; all new objects of class B that are created will get the new value
  • If an object of class B is create when one of class A does not exist yet, the object of class A needs to be created

The question now ... how do I build my classes, and make sure only one instance of class A is created?

Am I making sense?

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を注入するファクトリを用意し、クラスにインスタンスをコンストラクターパラメーターとして期待させることです。XBX

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に対して「setproperty」のようなメソッドを呼び出します。
  • オブジェクトXは、最初はnullである可能性のある参照に論理的に格納されます。nullの場合、オブジェクトBはコンストラクターに新しいオブジェクトXを作成できます。
  • オブジェクトBが独自にグローバルカラープロパティを変更する場合は、オブジェクトAへの内部参照を保持する必要があります。通知イベントの無限のループを防ぐために何かを行う必要があります(イベントソース(色を変更するオブジェクトBを渡す) )色の値などとともにオブジェクトXに)。

残念ながら、Bの新しいインスタンスが作成されると、どこかに存在する可能性のあるXに関する参照を取得する必要があります。これがグローバル静的フィールドにできない場合は、次のようになります。

  • バクテリアのようなオブジェクトBは、内部の非静的参照を渡すことができるように、互いに派生することしかできないと仮定しましょう。最初のインスタンスは、特別な方法で作成する必要があります。
  • ローカル変数を使用してX参照を保持できるメソッド/関数ですべてのオブジェクトBを作成するとします。
于 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 に答える