《K的技術學習筆記》——良好OOP的設計原則:<SOLID Principles>(六)
![](https://assets.matters.news/embed/7b7aee34-8f1e-4568-a323-0c037181f48a.png)
SOLID Principles的D就是依賴轉換(Dependency Inversion Principle)
依賴轉換(Dependency Inversion Principle)
用抽象觀念替代具體物件的關係。
現在大家都慣常在高層class中依靠著低層的class去完成高層class當中的method。可是當低層class有所改動時,高層class就要為了低層class的變動而自己都要作出改變。這就有違了開閉原則(Open–closed principle)。
依賴轉換(Dependency Inversion Principle)就是class當中不再依賴已實作好的class,而是使用抽象觀念來做相同的事。抽象觀念就是指Interface,Interface會大概規劃了能做什麼,但如何做就是之後實作的事。如何規劃Interface能做什麼,就要看看高層的class有什麼需求。這也就是為何依賴轉換了。本來是高層的class依靠低層的class,現在就是低層class依據高層class所需要Interface的規劃來實作。
現在用手機用家作為例子。
手機(Phone)
![](https://assets.matters.news/embed/4b0d48fd-26c8-4fbb-b475-c514cf834384.png)
正常手機可以用來打電話(call)和傳信息(message)。
蘋果電話(iPhone)
![](https://assets.matters.news/embed/c9f49f57-6fb7-41e4-8bfd-e59238af3a85.png)
蘋果電話可以用來看facebook(facebook)。
Android電話(AndroidPhone)
![](https://assets.matters.news/embed/3a3d80f5-a4e6-4134-b456-4e86bdf427fd.png)
Android電話可以用來看facebook(facebook)。
用家(User)
![](https://assets.matters.news/embed/b4c62746-0c50-45fa-9d01-b6ad425ade76.png)
用家(User)會持有一部手機(phone),用家可以使用他找人(find)和看facebook(facebook)。
當用家(User)要看facebook時,要先看看電話是不是iPhone或是Android Phone才能用這功能。當電話的種類增多時,用家(User)的code就要進行改動,例如,現在多了window phone,看facebook這個method就要加多一個window phone的判斷。
在這個例子裡高層指的是用家,而低層是指手機們。用家這層我會稱為應用層,手機們我會稱為工具層。我們看見應用層的動作都是依靠著工具層完成。因此,應用層是高層class,而工具層是低層class。當多了window phone這個新手機class,低層的結構就有所改變,而高層就要為此作出更動。
現在看看跟遵守依賴轉換(Dependency Inversion Principle)的寫法。
手機介面(Phone Interface)<遵守依賴轉換>
![](https://assets.matters.news/embed/1b16346f-a804-4e78-9c5b-583b3b989830.png)
這裡規劃了要有型號(modal),手機能打電話(call)和傳信息(message)。
智能手機介面(Smart Phone Interface)<遵守依賴轉換>
![](https://assets.matters.news/embed/36bf54c9-7cd0-427c-9530-d1f34b527ccc.png)
這裡繼承了手機介面及規劃智能手機能看facebook(facebook)。
蘋果電話(iPhone)<遵守依賴轉換>
![](https://assets.matters.news/embed/cc85cb5c-0e60-4faf-9320-29486d172e4f.png)
這裡實作了智能手機的所有功能,並設定了手機型號(modal)為iPhone。
Android電話(AndroidPhone)<遵守依賴轉換>
![](https://assets.matters.news/embed/6c19c38c-7179-437a-974f-acb6c7ea1307.png)
這裡實作了智能手機的所有功能,並設定了手機型號(modal)為Android。
用家(User)<遵守依賴轉換>
![](https://assets.matters.news/embed/138f6c48-7ca0-41b0-b0f4-2bba6eb43d52.png)
現在用家持有的手機只要符合智能電話介面(SmartPhone Interface)就可以了。他同樣能找人(find)和看facebook(facebook)。和之前不同的地方就是不用看手機的種類,便能看facebooke。這是因為我已經規劃了用家所持有的手機能做什麼。當再有新種類的電話時,我們不必再修改code了。
這裡應用層(指用家)先規劃了智能電話介面(SmartPhone Interface)能做什麼,而工具層就跟據這個介面來實作。因為應用層已經定了介面可以做什麼和工具層就跟著介面指示實作,所以工具層的變動都不會令應用層改變。
結論
遵守依賴轉換(Dependency Inversion Principle),可以減少了兩個class之間的依賴性,令其更容易擴展。這樣即使低層的class有所改動時,高層的class都不用去作出更動,少了更動出現bug的機會就會減少了,能做到這效果當前還有一個前題,就是code要遵守里氏替換原則(Liskov Substitution Principle)。這樣就更能遵守了以前提及過的開閉原則(Open–closed principle)。
Solid Principle就是一環扣一環才能做到這些效果,這篇也是關於Solid Principle的最後一篇,而依賴轉換(Dependency Inversion Principle)又能導出了依賴注入 (Dependency injection)和控制反轉 (Inversion of control),但由於這不是Solid Principle的一部份,我就在往後開新篇介紹。
喜欢我的作品吗?别忘了给予支持与赞赏,让我知道在创作的路上有你陪伴,一起延续这份热忱!
![](https://imagedelivery.net/kDRCweMmqLnTPNlbum-pYA/prod/avatar/23dcaa94-ad45-47a3-8255-4d2f5bc93a3e.jpeg/public)