2016-11-06 3 views
0
class A 
{ 
    public function doIt($c) 
    { 
     if (rand(0,1) == 1) // this means, we dont know if we need to create the object or not 
     { 
      $b = new B($c); 
     } 
    } 
} 

class B 
{ 
} 

class C 
{ 
} 

$c = new C(); 
$a = new A(); 
$a->doIt($c); 

問題は、Aは、$c、または約Cを知っている必要はありません。それでも、Bで処理するには、それを渡す必要があります。それは悪い兆候ではありませんか? ABとは関係がないので、私はそうだと思います。DI、それを手渡すだけのオブジェクトを追加するのは悪い兆候ですか?

+1

はそれがより良いと思いませんか? 'C'のインスタンスは約50%少なくなります。 –

+1

後で '$ b'で何をしますか? – chelmertz

+1

ランダムな部分は質問と何を関係していますか?私はそのif文の有無が問題の核心に何らかの違いをもたらすとは考えていません。それは悪い設計ですか? – trincot

答えて

1

これを改善するには、dependency injectionパターンを使用します。そうすれば、Aインスタンスは$cを知る必要はなく、Bインスタンスを作成する方法さえも知る必要はありません。

代わりに、インジェクタ機能、ABのインスタンスを取得するために呼び出す必要がある、すなわち、コールバックでAインスタンスを提供します。

このようにして、元のコードの利点を失うこともありません。Bのインスタンスは、必要なときにのみ作成されます。しかし、この利点もCインスタンスの作成に拡張されます。

class A { 
    public function doIt(Callable $factory) { 
     $b = 'nothing'; 
     if (rand(0,1) == 1) { 
      // Call the callback to get the B instance: 
      $b = $factory(); 
     } 
     // other code... 
     // 
     return $b; 
    } 
} 

class B { } 

class C { } 

$a = new A(); 
$b = $a->doIt(function() { 
    $c = new C(); 
    return new B($c); 
}); 
var_dump($b); 

注:必要なときにのみ作成されますがAが必要な場合にのみ、その後、あなたはdoItメソッドを作成することを検討するもののようなタイプを行うには方法はstaticです。そして、あなたが実際にAのインスタンスを作成する必要はありません:あなたは `A`で` if`の内部 'C'のインスタンスを作成する場合

class A { 
    public static function doIt(Callable $factory) { 
     // ...etc 
} 
// ... 

$b = A::doIt(function() { 
    return new B(new C()); 
}); 
関連する問題