2012-08-24 37 views

回答

3

這種模式就可以了(實際上是一個默認的備用類類型的概念中,(反)模式有一個name - BastardInjection),但也有關於這種方法的問題:

  1. 通過在消費者CL構造一個新的MyNewDefaultService()依賴屁股,除了抽象之外,你還要結合一個具體的服務類。在編譯語言中,這也意味着您的消費代碼現在需要對包含具體依賴類的jar/library/dll/assembly進行「引用」,而如果您省略直接構建,則可以僅在界面上進行耦合。在腳本語言中,您需要確保在運行時可以解析具體的依賴關係。

  2. 依賴關係MyNewDefaultService的生命週期管理現在被硬編碼爲與消費類的生命週期相同。由IoC容器注入和管理的對象的生命週期可以給你更多的靈活性(例如注入共享對象等)。因爲你不能嘲笑「默認」路徑(即當$service == null),所以你需要混合使用單元測試(對於注入路徑和模擬依賴)和集成測試(集成測試)對於默認路徑)來證明您的代碼的正確性。

  3. 如果您的依賴項本身具有其他依賴項,也使用構造函數注入,那麼缺省構造路徑很快就會變得笨拙,並導致更多的耦合,因爲您現在需要做所有的努力解決依賴關係,您的IoC容器會爲你做的,例如

if(null === $service){ 
    $service = MyNewDefaultService(RepoFactory.Create(LoggerFactory.Create()), ...) 
} 

TL; DR雖然,而你是從耦合的層次結構遷移到由IoC容器管理的鬆耦合依賴注入的層次結構中此方法可能會在一個短暫的階段,成爲一個有用的,只有構造函數只有一條路徑時,纔會完全實現Dependency Inversion Principle的真正好處,即將抽象耦合到所有依賴關係,而不是任何具體實現。

+0

那麼你是在暗示,如果一個類需要一個服務然後注入該對象並且不提供默認的回退類?我的推理以及爲什麼我這麼做的原因是爲了減少創建對象並將事情捆綁在一起的前期工作量。我的應用程序只是一個玩具應用程序,目前正試圖學習這些概念,但我確定我想正確完成工作以學習 – user1572427

+0

@ user1572427從純粹的角度來看,是的,您應該將構造/使用壽命留給容器。不過,我之前使用過混合模式,例如當一位客戶表示他們'還沒有使用DI,但將來可能會這樣做'時,混合動力車就會給出一些未來的證明。不要硬編碼新的,而是考慮使用一個classfactory。 – StuartLC