依賴倒轉原則又稱依賴倒置原則:數據庫
抽象不該該依賴細節,細節應該依賴於抽象。說白了,就是針對接口編程,不要針對實現編程。編程
依賴倒置原則包括三層含義:函數
1)高層模塊不該該依賴低層模塊,二者都應該依賴其抽象;post
2)抽象不該該依賴細節;spa
3)細節應該依賴抽象。對象
看了上面的解釋相信你們會和我同樣會有一些疑問在腦海裏,如下來具體說一說吧:繼承
1)爲何要針對接口編程,而不是針對實現編程呢?接口
很是easy的一個樣例。咱們現在使用的電腦有各式的品牌。聯想、神舟、戴爾等等,開發
電腦需要用到鼠標,鍵盤;若是鼠標、鍵盤是針對某一個品牌的機器實現去作的話,那麼咱們將會遇到什麼問題呢?it
那麼咱們市面上的鍵盤和鼠標就都是各式各樣的,有一天鼠標。或鍵盤壞了。咱們要怎麼去買呢?難道記住這個電腦是什麼品牌。什麼型號,還有什麼類型的去買麼?這樣會瘋掉的。現在咱們的電腦基本上都是使用USB接口的了,無論是鍵盤也好,鼠標也好,咱們僅僅要買USB接口的就可以使用了,同一時候,使用USB接口還可以有其它的擴展。僅僅要實現了,這個接口,實現怎麼樣都不要緊。好比,實現了USB接口的小檯燈,僅僅要接上USB線就可以照明瞭;又如實現了USB
接口的充電器,接到咱們的電腦上就可以充電了。
2)高層模塊不該該依賴低層模塊,二者都應該依賴其抽象又怎樣理解呢?這個問題也可以這麼問:爲何要叫倒置(倒轉)呢?
在面向過程的開發中,爲了使用常常使用的代碼可以複用,通常都會把這些常常使用的代碼寫成許不少多函數的程序庫,這樣咱們作新項目的時候,就去調用這些函數就可以了。
好比:咱們作的項目大多要訪問數據庫。因此咱們就把數據庫的代碼寫成了函數,每次作新項目時就去調用這些函數。這也就是高層依賴於低層模塊了。
問題就出現在這裏了,咱們在作新項目的時候,會發現業務邏輯的高層模塊是同樣的,咱們但願能重用這些高層模塊。但是這些高層模塊和低層模塊的數據庫綁定在一塊兒了,這樣咱們就沒辦法複用這些高層模塊了。
假設咱們的高層模塊和低層模塊都依賴於抽象,詳細一點就是依賴於接口或抽象類。僅僅要接口夠穩定。那麼不論什麼一個的更改都不用操心其它受到影響了。
3)爲何依賴了抽象的接口或是抽象類。就不怕更改了呢?要解決問題,先看看里氏替換原則。
里氏替換原則:
一個軟件實體假設使用的是一個父類的話,那麼必定適用於其子類,而且它察覺不出父類對象和子類對象的差異。
也就是說。在軟件裏面。把父類都替換成它的子類。程序的行爲沒有變化;
簡單的說:子類型必須能夠替換掉它們的父類型。好比:企鵝在生物學分類上是屬於鳥的,但是在編程中,企鵝就不能以父類的(鳥)的身份出現。
若是有一個鳥的父類,擁有一個會飛的方法fly(),咱們是不能讓企鵝繼承於鳥的,這樣當子類可以替換掉父類,軟件單位的功能不受到影響時,父類才幹真正的被複用,
而子類也能夠在父類的基礎上加入新的行爲。
好比:貓是繼承動物類的,以動物的身份擁有吃、喝、跑、叫等行爲。
可當某一天。咱們需要狗、牛、羊也擁有相似的行爲。由於它們都是繼承於動物,因此除了更改實例化的地方,程序其它地方就需要改變了。
正是由於子類型的可替換性才使得使用父類類型在的模塊在無需改動的狀況下就可以擴展。UML圖:
高層模塊依賴於接口或抽象類。低層模塊實現接口或抽象類。依賴倒置原則事實上就是誰也不依靠誰。除了約定的接口,這樣你們都可以靈活自由了。