所謂依賴倒置原則(Dependence Inversion PRinciple )就是要依賴于抽象,不要依賴于具體。簡單的說就是對抽象進行編程,不要對實現(xiàn)進行編程,這樣就降低了客戶與實現(xiàn)模塊間的耦合。
面向過程的開發(fā),上層調(diào)用下層,上層依賴于下層,當下層劇烈變化時,上層也要跟著變化,這就會導(dǎo)致模塊的復(fù)用性降低而且大大提高了開發(fā)的成本。 面向?qū)ο蟮拈_發(fā)很好的解決了這個問題,一般的情況下抽象的變化概率很小,讓用戶程序依賴于抽象,實現(xiàn)的細節(jié)也依賴于抽象。即使實現(xiàn)細節(jié)不斷變化,只要抽象不變,客戶程序就不需要變化。這大大降低了客戶程序域?qū)崿F(xiàn)細節(jié)的耦合度。
抽象不應(yīng)該依賴細節(jié),細節(jié)應(yīng)該依賴于抽象。說白了,就是針對接口編程,不要針對實現(xiàn)編程。
依賴倒置原則包含三層含義:
1)高層模塊不應(yīng)該依賴低層模塊,兩者都應(yīng)該依賴其抽象;
2)抽象不應(yīng)該依賴細節(jié);
3)細節(jié)應(yīng)該依賴抽象。
依賴倒置有三種方式來實現(xiàn)1、通過構(gòu)造函數(shù)傳遞依賴對象; 比如在構(gòu)造函數(shù)中的需要傳遞的參數(shù)是抽象類或接口的方式實現(xiàn)。
2、通過setter方法傳遞依賴對象; 即在我們設(shè)置的setXXX方法中的參數(shù)為抽象類或接口,來實現(xiàn)傳遞依賴對象。
3、接口聲明實現(xiàn)依賴對象,也叫接口注入;
即在函數(shù)聲明中參數(shù)為抽象類或接口,來實現(xiàn)傳遞依賴對象,從而達到直接使用依賴對象的目的。
為方便理解,舉一些生活中的例子:1、AGP插槽。主板和顯卡之間關(guān)系的抽象。主板和顯卡通常是使用AGP插槽來連接的,這樣,只要接口適配,不管是主板還是顯卡更換,都不是問題。
2、駕照。司機和汽車之間關(guān)系的抽象。有駕照的司機可以駕駛各種汽車。
3、電源插座。 設(shè)計模式中最能體現(xiàn)DIP原則的是抽象工廠模式。在抽象工廠模式中,工廠和產(chǎn)品都可以是抽象的,如果客戶要使用的話,只要關(guān)注于工廠和產(chǎn)品的接口即可,不必關(guān)注與工廠和產(chǎn)品的具體實現(xiàn)。
DIP對于并行開發(fā)的影響:兩個類之間有依賴關(guān)系,只要制定出他們之間的接口,就可以并行開發(fā)了。
備注: 1、什么叫做高層模塊依賴于底層模塊?
面向過程的開發(fā)時,為了復(fù)用一些常用代碼,通常會把這些代碼寫成函數(shù)庫的形式。這樣,以后做新項目時,調(diào)用這些底層函數(shù)就可以了。這就叫做高層模塊依賴于底層模塊。 高層模塊一般和業(yè)務(wù)邏輯相關(guān),底層模塊一般和具體實現(xiàn)相關(guān)。
2、何謂“倒置”?
這是因為傳統(tǒng)的軟件開發(fā)方法,如結(jié)構(gòu)化的分析和設(shè)計,傾向于創(chuàng)建高層模塊依賴于低層模塊、抽象依賴于具體的軟件結(jié)構(gòu)。實際上,這些方法的目標之一就是去定義描述上層模塊如何調(diào)用低層模塊的層次結(jié)構(gòu)。所以,相對于傳統(tǒng)的過程化的方法通常所產(chǎn)生的那種依賴結(jié)構(gòu),一個設(shè)計良好的面向?qū)ο蟮某绦蛑械囊蕾嚱Y(jié)構(gòu)就是“被倒置”的。 來看一下那些依賴于低層模塊的高層模塊的含義。一個應(yīng)用中的重要策略決定及業(yè)務(wù)模型正是在這些高層的模塊中。也正是這些模型包含著應(yīng)用的特性。但是,當這些模塊依賴于低層模塊時,低層模塊的修改將會直接影響到它們,迫使它們也去改變。這種境況是荒謬的。應(yīng)該是處于高層的模塊去迫使那些低層的模塊發(fā)生改變。應(yīng)該是處于高層的模塊優(yōu)先于低層的模塊。無論如何高層的模塊也不應(yīng)依賴于低層的模塊。而且,我們想能夠復(fù)用的是高層的模塊。通過子程序庫的形式,我們已經(jīng)可以很好地復(fù)用低層的模塊了。
當高層的模塊依賴于低層的模塊時,這些高層模塊就很難在不同的環(huán)境中復(fù)用。但是,當那些高層模塊獨立于低層模塊時,它們就能很簡單地被復(fù)用了。這正是位于框架設(shè)計的最核心之處的原則。
新聞熱點
疑難解答