舉個栗子,咱們的電腦藍屏了,通常是內存條壞了,這時候咱們只須要更換內存條就能夠保證電腦從新正常運行。數據庫
可是若是是收音機壞了,咱們每每有種無從下手的感受,爲何複雜的電腦容易修而簡單的收音機卻這麼難修呢?編程
依賴倒轉原則函數
A.高層模塊不該該依賴底層模塊。兩個都應該依賴抽象。spa
B.抽象不該該依賴細節。細節應該依賴抽象。設計
爲何要叫倒轉呢?對象
面向過程開發時,爲了使代碼複用,通常都會把這些代碼寫成許多函數的程序庫,作項目時只須要調用這些低層的函數庫就能夠了。繼承
好比咱們作的項目大多要訪問數據庫,因此咱們把數據庫的代碼寫成函數,每次調用就能夠了,這就叫作高層模塊依賴低層模塊。接口
但客戶但願使用不一樣的數據庫或存儲方式,麻煩就出現了,由於高層模塊都是和底層的訪問數據庫綁定在一塊兒的,沒辦法複用這些高層模塊。內存
就像電腦若是CPU、內存、硬盤都須要依賴主板,主板一壞,全部部件就都沒用了。反過來,內存壞了也不該該形成其餘部件不能使用纔對。開發
若是無論高層模塊仍是低層模塊,都依賴於抽象,具體點就是接口或抽象類,只要接口是穩定的,那麼任何一個更改都不用擔憂其餘受到影響,這就使得高低模塊均可以複用。
爲何依賴了抽象的接口或抽象類,就不怕更改呢?
里氏代換原則
子類型必須可以替換掉他們的父類型。
面相對象設計時,一個是鳥類,一個是企鵝類,若是鳥是能夠飛的,企鵝不會飛,那麼企鵝是鳥嗎?企鵝能夠繼承鳥這個類嗎?
按咱們現實的角度,企鵝是一種特殊的鳥,儘快不能飛,但他也是鳥,固然能夠繼承
可是在面向對象設計時,子類擁有父類全部非private的行爲和屬性。鳥會飛,而企鵝不會飛。
儘快在生物學的分類上企鵝是一種鳥,但在編程世界裏,企鵝不能以父類——鳥的身份出現。由於前提說全部鳥都能飛,而企鵝飛不了,因此企鵝不能繼承鳥類。
也正由於有了這個原則,使得繼承複用成爲了可能
只有當子類能夠替換掉父類,軟件單位的功能不受影響時,父類才能真正被複用,而子類也可以在父類的基礎上增長新的行爲。
也正由於有了里氏替換原則,纔是的開放-封閉成爲了可能,正是因爲子類的可替換性才使得使用父類類型的模塊在無需修改的狀況下就能夠擴展。
依賴倒轉起始就是誰也不須要依賴誰,除了約定的接口,你們均可以靈活自如。
收音機就是典型的耦合過分,只要收音機出現故障,無論是沒有聲音、不能調頻仍是有雜音,反正都很難修理,由於各個部件相互依賴,難以維護。
依賴倒轉能夠說是面向對象設計的標誌,用哪一種語言不重要,若是編寫時考慮的都是如何針對抽象編程而不是針對細節編程,
即程序中全部的依賴關係都是終止於抽象類或接口,那就是面向對象的設計,反之那就是過程化的設計了。