我最近開始閱讀關於依賴注入的知識,它讓我重新思考一些我的設計。PHP懶惰加載對象和依賴項注入
我的問題是這樣的: 比方說,我有兩個類:車客; 對於這兩個類,我有一些數據映射器與數據庫的工作:CarDataMapper和PassengerDataMapper
我希望能夠在代碼中做這樣的事情:
$car = CarDataMapper->getCarById(23); // returns the car object
foreach($car->getPassengers() as $passenger){ // returns all passengers of that car
$passenger->doSomething();
}
之前,我知道DI什麼,我將建立我的課是這樣的:
class Car {
private $_id;
private $_passengers = null;
public function getPassengers(){
if($this->_passengers === null){
$passengerDataMapper = new PassengerDataMapper;
$passengers = $passengerDataMapper->getPassengersByCarId($this->getId());
$this->setPassengers($passengers);
}
return $this->_passengers;
}
}
我也有類似的代碼在Passenger-> getCar()方法來獲取車裏的乘客在
。我現在明白,這會在Car和Passenger對象和數據映射器對象之間創建依賴關係(當然,我也瞭解它,但我並不知道這是「錯誤的」)。
雖然冥思苦想此兩個選項的解決方案來考慮,但我真的不喜歡任何人:
1:做這樣的事情:
$car = $carDataMapper->getCarById(23);
$passengers = $passengerDataMapper->getPassengersByCarId($car->getId());
$car->setPassengers($passengers);
foreach($car->getPassengers() as $passenger){
$passenger->doSomething();
}
但什麼如果乘客有需要注入的對象,並且如果嵌套達到十到二十個層次,我會結束實例化幾乎每個對象,在我的應用程序開始時,它會在整個過程中查詢整個數據庫。 如果我必須將乘客發送給另一個必須對乘客所持物品進行操作的物體,我不想立即將這些物體實例化。
2:注入數據映射器到汽車和乘客的對象,並且具有這樣的事情:
class Car {
private $_id;
private $_passengers = null;
private $_dataMapper = null;
public function __construct($dataMapper){
$this->setDataMapper($dataMapper);
}
public function getPassengers(){
if($this->_passengers === null && $this->_dataMapper instanceof PassengerDataMapper){
$passengers = $this->_dataMapper->getPassengersByCarId($this->getId());
$this->setPassengers($passengers);
}
return $this->_passengers;
}
}
我不喜歡這樣更好,因爲它不喜歡的車是真的不知道數據映射器,並沒有數據映射器,汽車可能表現不可預知(不返回乘客,當它實際上有他們)
所以我的第一個問題是: 我在這裏採取了一個完全錯誤的方法,因爲越多我看它,它看起來越像我構建一個ORM,而不是一個業務層?
第二個問題是: 是否有一種方法可以實際將對象和數據映射器分離開來,這樣就可以使用第一個代碼塊中描述的對象?
第三個問題: 我已經看到了其他語言解決這個問題的是這樣一些答案(有些版本的C,我認爲)這裏描述: What is the proper way to inject a data access dependency for lazy loading? 由於我沒有來得及與其他玩語言,這對我來說沒有意義,所以如果有人會在PHP-ish的鏈接中解釋這些例子,我將不勝感激。
我也查看了一些DI框架,並閱讀了關於DI Containers和Inversion of Control的內容,但是根據我的理解,它們用於定義和注入「非動態」類的依賴關係,例如Car依賴於引擎,但它不需要從數據庫動態加載引擎,它只會被實例化並注入汽車。
對不起,冗長的職位,並提前感謝。
您可能想要結帳[PoEAA](http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420/ref=sr_1_1?ie=UTF8&qid=1350785602&sr=8-1&keywords=模式+ +企業+應用程序+架構)雖然它根本無法幫助[DI](http://martinfowler.com/articles/injection.html)(它早於共同點),但您會意識到,即使您業務層您需要一個位於其下的ORM。建議使用[Data Mapper](http://martinfowler.com/eaaCatalog/dataMapper.html)。 +1提出我一直在尋找答案的問題。 – xenoterracide 2012-10-21 02:16:06
感謝您的提示。最近我在我的大部分項目中都使用了Doctrine2,這是一個Data Mapper ORM,並且很容易處理。 – Pinetree 2012-10-21 06:02:28