2016-08-21 5 views
1

は、私は両方がそうのように互いに依存する2つのクラスをインスタンス化します。この鶏肉や卵の問題を「エレガントな」方法で解決するにはどうすればいいですか?または、メソッドを使用してインスタンス化した後にbへの参照を設定する必要がありますか?循環参照のインスタンス

+0

「A」と「B」のコンストラクタで行います。例えば。 'A'の場合、' null 'を渡した場合は 'this.b = new B(this);'を設定します。 'B'が' a!= null'を渡されると、再帰が終了します。 'A'と' B'が入れ替えられたのと同じ方法です。 – Siguza

+2

私は両方のオブジェクトがインスタンス化された後にループを完了するためにセッターを使うことが唯一の方法だと思います。 – Claudiu

答えて

1

この問題をABのコンストラクタに移動することをお勧めします。

あなたがこの場合の条件(間接)再帰活用することができます:||を使用することにより

function A(b) 
{ 
    this.b = b || new B(this); 
} 
function B(a) 
{ 
    this.a = a || new A(this); 
} 

を、あなたはこのように終わる、それぞれA(this)B(this)への呼び出し自体は別のB/Aを作成しないことを保証します」鶏肉/卵 "問題。

次に、あなたはAまたはBが合法的nullに自分の.bまたは.aセットを持っている場合がある場合は、あなたがundefinednullを使用することができます

this.a = new A(); 
this.b = this.a.b; 

または

this.b = new B(); 
this.a = this.b.a; 

のようにそれらを使用することができますこれらのケースを区別して、それに応じてコンストラクタを変更します。

function A(b) 
{ 
    this.b = b === undefined ? new B(this) : b; 
} 
function B(a) 
{ 
    this.a = a === undefined ? new A(this) : a; 
} 

もしABは、それがabフィールドを保持しているので、あなたは(作成範囲からそれらをthisインスタンスを渡すことができ、そのコンストラクタに他の引数を必要とする、またはその他の理由で別のBまたはA自分自身を構築するべきではありませんその値ABが構成されている場合)、アクセスされたときのみが判定される。

function A(container) 
{ 
    this.container = container; 
    // Access B via this.container.b 
} 
function B(container) 
{ 
    this.container = container; 
    // Access A via this.container.a 
} 
this.a = new A(this); 
this.b = new B(this); 

ABが完全ACを有するように意図されていない場合コンテナオブジェクトに目的税、あなたのような、その代わりに使用される仲介オブジェクトを作成することができます。それが何らかの理由でも受け入れられない場合は、あなたの唯一のオプションは後でa.bb.aの値を変更することです

var aProxy = { a: null }; 
var bProxy = { b: null }; 
this.a = aProxy.a = new A(bProxy); 
this.b = bProxy.b = new B(aProxy); 

手動割り当てまたはセッター機能を介して実行される。

+2

しかし、このアプローチでは、コンテナに作業をさせてインスタンスを渡す代わりに、2つのクラス自体を緊密に結合していることに注意してください。 – Bergi

+0

これは私にとってはうまくいかない理由です。少し汚れていてもセッターで割り当てをしなければならないと思う。 – landunder

+0

@landunder最初の2つのアプローチはクラスを結びつけ、後者の2つのクラス(AとBはコンテナを渡す)は結合しません。 – Siguza