2016-11-06 1 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); 

Das Problem ist, A muss nicht $c oder über C wissen. Dennoch müssen wir es übergeben, nur um es auf B zu behandeln. Ist das kein schlechtes Zeichen? Ich denke es ist, seit A hat nichts mit B zu tun.DI, ist es ein schlechtes Zeichen, ein Objekt hinzuzufügen, nur um es weiterzugeben?

+1

Wäre es nicht besser, wenn Sie Instanz von 'C' innerhalb von 'if' in' A' erstellen? Es würde etwa 50% weniger "C" geben. –

+1

Was wirst du später mit '$ b' machen? – chelmertz

+1

Was hat der Zufallsteil mit der Frage zu tun? Ich glaube nicht, dass das Vorhandensein oder Fehlen dieser 'if' Aussage für den Kern der Frage einen Unterschied macht: ist es schlechtes Design? – trincot

Antwort

1

Sie könnten dies verbessern, indem Sie ein dependency injection Muster verwenden. Auf diese Weise muss die A Instanz nicht über $c oder sogar wissen, wie eine B Instanz erstellt wird.

Stattdessen würden Sie die A Instanz mit der Funktion Injektor liefern, das heißt ein Rückruf dass A Bedürfnisse zu fordern, um eine Instanz von B zu bekommen.

Auf diese Weise verlieren Sie auch nicht den Vorteil, den Sie im ursprünglichen Code hatten: Die Instanz B wird nur bei Bedarf erstellt. Aber dieser Vorteil auch für die Schaffung der C Instanz erweitert: es wird nur erstellt, wenn nötig:

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

Hinweis: Wenn Sie A brauchen nur diese Art von Dingen zu tun, dann können Sie die doIt Methode zu schaffen betrachten als eine static Methode. Dann würden Sie nicht brauchen, um tatsächlich eine Instanz von A zu erstellen:

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

$b = A::doIt(function() { 
    return new B(new C()); 
}); 
Verwandte Themen