java提出的依賴注入標準,有別於如下傳統的對象獲取方式java
開發過程當中是會有不少層層依賴的對象的,例如,Stopwatch依賴於TimeSource,爲當前對象尋找一個所依賴對象的實例稱作解決依賴,若沒有實例被找到,則應用執行失敗,咱們稱依賴不知足服務器
當沒有依賴注入時,也有不少解決依賴的方法,例如直接調用構造器單元測試
class Stopwatch { final TimeSource timeSource; Stopwatch() { timeSource = new AtomicClock(...); } void start() {...} void stop() {...} }
若是須要更多的靈活性,可使用工廠方法測試
class Stopwatch { final TimeSource timeSource; Stopwatch() { timeSource = DefaultTimeSource.getInstance(); } void start() {...} void stop() {...} }
咱們必須權衡這兩種方式:this
並且,這幾種方法都限制了單元測試,例如,若是咱們使用工廠方法,全部依賴於依賴於工廠類的測試代碼都須要模擬出factory,還要記得在用完以後清理掉它pwa
void testStopwatch() { // 先獲取原始的實例 TimeSource original = DefaultTimeSource.getInstance(); // 用mock數據替換原始實例 DefaultTimeSource.setInstance(new MockTimeSource()); try { Stopwatch sw = new StopWatch(); ... } finally { // 將原始實例放回去以免一些風險 DefaultTimeSource.setInstance(original); } }
實踐經驗告訴咱們,模擬factor會致使大量的模式化代碼,大量的模擬和清理將會很快失控。code
依賴注入解決了全部的這些問題對象
class Stopwatch { final TimeSource timeSource; @Inject Stopwatch(TimeSource timeSource) { this.timeSource = timeSource; } void start() {...}; void stop() {...}; }
構造器進一步的將依賴層層傳遞,直到知足所有依賴。例如,咱們須要構造一個StopwatchWidget實例:開發
class StopwatchWidget { @Inject StopwatchWidget(Stopwatch sw) {...} }
構造器作了什麼get
這使咱們的代碼看起來更加簡潔和靈活,並從必定程度上弱化了依賴關係
在測試用例中,咱們也能夠直接經過像構造器傳遞模擬數據進行單元測試,不再須要設置/清理factories了
void testStopwatch() { Stopwatch sw = new Stopwatch(new MockTimeSource()); }