2016-11-06 51 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

豈不是更好?會有大約50%的'C'實例少。 –

+1

稍後您將如何處理'$ b'? – chelmertz

+1

隨機部分與這個問題有什麼關係?我不認爲這個「if」陳述的存在或缺失對問題的核心有什麼影響:這是不好的設計嗎? – trincot

回答

1

您可以通過採用dependency injection模式進行改進。這樣A實例不需要知道關於$c,甚至不需要知道如何創建B實例。

相反,你將提供A實例與注射器功能,即一個回調A需要,以獲得B實例調用。

這樣,您也不會失去原始代碼中的優勢:僅在需要時纔會創建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()); 
}); 
相關問題