2013-12-09 35 views
2

看看下面的代碼的我想要什麼的例子:如何實現使用PHP工廠類 - 扶養注射

class SomethingController extends Factory  
{ 
    private $somethingRepository; 

    public function __Construct(ISomethingRepository $repo) 
    { 
     $this->somethingRepository = $repo; 
    } 
} 

class Factory 
{   
    public function __Construct() 
    { 
     // The following call to AddBinding would push into SomethingController the new instance of the class denoted in my AddBinding second parameter. 
     $this->AddBinding(ISomethingRepository, MySQLSomethingRepository); 
     // So in this case, if the controller i'm extending has a construct parameter of ISomethingRepository, then make the parameter equal a new MySQLSomethingRepository() 
     // Then if I want to use JSONSomethingRepository in the future, I only have to change the one AddBinding call and the controller will still work. 
    } 

    public function AddBinding($interface, $concrete) 
    { 
     // Somehow assign the constructor properties of the extending class as new instances of the bindings i have called upon in the construct of my factory class (see this class's construct) 
     // Pseudo code: 
     // ---------------------- 
     $calledClass = get_called_class(); 
     $class = new \ReflectionClass($calledClass); 

     $method = $class->getMethod("__construct"); 

     $params = $method->getParameters(); 

     foreach($params as $param) 
     { 
      if ($param == $interface) 
      { 
       return new $concrete; 
      } 
     } 
     // /Pseudo code: 
     // ---------------------- 
    } 
} 

我想實現一個工廠一種類。

  • 此工廠類將由控制器類擴展。
  • 工廠類將着眼於控制器類的結構參數,並根據關在廠裏我AddBindings方法的對象的新實例。

比方說,我想有哪些有數據從MySQL未來的一個MySQLSomethingRepository ...注入到我的SomethingController ......帶我需要聲明

SomethingController(new MySQLSomethingRepository())... 

它希望能與被處理我的工廠類...

目前的方法,我做這件事是強制直接連接與數據源...這使得它很難做到的測試用例:

private $somethingRepository = new MySQLSomethingRepository(); 

所以想象一下,如果我在其他控制器的負載使用此相同的存儲庫,我想我的數據庫源改變一些JSON數據,我實現以下庫「JsonSomethingRepository」,我得去和所有的控制器更改爲:

private $somethingRepository = new JsonSomethingRepository(); 

如何可能我實現了我的工廠類,以便它可以處理創建我的控制器類的AddBindings函數內部苛刻的情況下?

+0

請看看這個初學者:http://stackoverflow.com/questions/18853199/is-extending-class-good-practice/18853389#18853389 – deceze

回答

0

設計的適配器模型的抽象類,併爲子類的一些常用方法。 您可以將兩個repos與適配器一起設計爲注入到您的控制器中。

我recommendtation是使用abstract class和做如下方式:

class SomethingController extends AbstractController { 
} 

abstract class AbstractController { 
    protected $somethingRepository; 
    public function __Construct(ISomethingRepository $repo) { 
     $this->somethingRepository = $repo; 
     $this->AddBinding (ISomethingRepository, MySQLSomethingRepository); 
    } 
    public function AddBinding($interface, $concrete) { 
     // Somehow assign the constructor properties of the extending class as new instances of the bindings i have called upon in the construct of my factory class (see this class's construct) 
    } 
} 

希望這將是幫助。

+0

哦,上帝,給我一點時間讓我的頭這.. wehey,頭。 – Jimmyt1988

+0

我仍然需要在類型提示上做一些if語句。 – Jimmyt1988

+0

@JamesT你可以更新你的問題在代碼中詳細說明嗎? – Snowwolf