2017-05-19 147 views
0

我明白依賴注入是什麼,但我還沒有看到它的全貌如何對消費者有利。見下面的例子。依賴注入框架 - 依賴關係傳播

//bad 
class car() { 
    var tire = new Tire('snow'); 
} 

//good 
class car() { 
    var tire; 
    constructor(tire){ 
    this.tire=tire 
    } 
} 

所以大多數文章我已閱讀狀態,上面的例子是好的,因爲它消除了汽車輪胎的依賴,從而變得更加可測試。但是另一個實例化汽車物體的類呢?如果一個driver類召喚car類,那麼不會強制驅動程序實例化car對象,也不會強制執行tires。看起來好像依賴總是被傳播得更遠。這到底在哪裏?實際實例化對象的是什麼?這是DI框架的全部內容嗎?

+1

簡而言之:是的,它一直在「傳播」,是的,這就是DI框架可以簡化的地方。 – deceze

回答

1

您是正確的依賴需求得到「傳播」的所有方式。想要實例化他們的汽車的駕駛員需要帶上CarTires。有許多驅動程序的驅動程序池需要帶上Driver s,Car s和Tire等,等等。打擊這種簡單的方法就是捆綁的東西到工廠:(只用於說明目的,見下文)

class Driver { 
    constructor(carFactory) { 
     this.car = carFactory.newCarWithRegularTires(); 
    } 
} 

你可以注入不同的工廠,可以創建其他車,而Car的依賴關係可以改變,不需要Driver需要知道這一點。

更進一步,您可以創建一個通用的全局工廠,它可以創建各種對象並知道如何滿足每個對象的依賴關係,這是一個依賴注入容器。您通常以文本格式配置它們,聲明Car需要Tire,並且當您要求它爲Car的實例時,它知道首先實例化Tire並傳遞它。

DI容器的缺點是,儘管您仍然可以通過重新配置DI容器來交換依賴關係,但這有時意味着您必須重新配置整個事物,並且它變成了巨大的相互依賴的對象註冊表。你應該避免創建一個巨大的容器,但要保持模塊化。

工廠的另一個詞:上面的工廠的例子不是很好。如果對象需要在運行時創建對象的新實例,則應該使用工廠。它應該而不是使用工廠只是爲了滿足可以直接注入的依賴關係。最後,你希望在類之間取得平衡,直接聲明和接收它們的依賴關係,但也不會創建非常深的依賴關係層次結構。保持依賴關係儘可能淺是一個好的開始,在狀態點引入工廠或模塊化DI容器是另一種方式。

+0

很棒的回答。爲了驗證我的理解,你說實例化對象是不可避免的。這完全是爲了保持依賴關係層次結構儘可能簡單和儘可能淺,並在需要時使用工廠。你有什麼經驗法則可以在你這樣做時引導你? – alaboudi

+1

不會超越「當它開始變成一種痛苦時,退後一步並重構。「 - 對象應該直接在它們的構造函數中使用它們的依賴關係,這個構造函數基本上定義了依賴關係圖,這個關係圖在頂部變得越來越寬.DI容器/工廠再次縮小了圖形,但也引入了更多的綁定,並且變得難以替換。您的圖表上的戰略點適合他們。 – deceze