依賴倒置原則就看這篇,7張圖解徹底吃透,架構設計築基必知必會
來源:mikechen的網際網路架構
依賴倒置是確保架構設計靈活性、擴充套件性的重要原則。
把依賴方向搞反,是經常出現的典型錯誤。依賴關係沒處理好,就會導致一個小改動,影響一大片。
結構化的程式設計思路,是自上而下進行功能分解,再按照分解結果進行組合的。這個思路很自然就延續到了很多人的程式設計習慣中。
本文,我們將透過手工圖解、原始碼示例,來全面解析依賴倒置原則。
大家好,我是 mikechen。
依賴倒置是良好架構設計的基石,社/校招面試常問,必知必會非常重要。為方便大家系統學習,我已將本文歸納到《阿里架構師進階專題合集》。需要的同學,拉到文末自取。
依賴倒置原則(DIP),英文全稱 Dependency Inversion Principle。
顧名思義,就是將傳統的依賴關係顛倒過來,讓高層模組和底層模組都依賴於抽象介面。
依賴倒置之所以被提出,是源自它所提倡的軟體設計原則。
依賴倒置原則的兩個核心思想:
1) 高層模組不應依賴於底層模組,高層模組、底層模組都應依賴於抽象。
2) 抽象不應該依賴於細節,細節應該依賴於抽象。
這意味著,
在軟體設計中,應該使用抽象類、介面或抽象方法等抽象層,來定義模組之間的通訊介面。而具體實現,應該依賴於這些抽象。
一圖釋義:
抽象的關鍵在於:
它提供了一種通用的、高層次的方式,來定義模組之間的介面和互動,而不關心具體的實現。
高層模組將依賴於這個抽象,而不是直接依賴於底層模組的具體細節。
在依賴倒置原則中,抽象可以透過抽象類、介面或抽象方法來實現。
依賴倒置改變了傳統的依賴關係。
依賴倒置從具體細節轉移到了抽象上,極大提高了系統的靈活性、可維護性和可擴充套件性。
在傳統的依賴關係中,高層模組直接依賴於底層模式的實現細節。
高層模組需要了解並依賴於底層模組的內部細節,包括其資料結構、演算法和邏輯。
由於高層模組與底層模式是一種緊耦合的關係,當底層模組結構發生變化時,高層就需要隨之改變。
一個小的變更,可能導致大範圍的程式碼修改和測試。
傳統依賴的架構設計很不合理,系統結構太剛性,難以維護及擴充套件。
傳統依賴 VS 依賴倒置:
再來對比下傳統依賴、依賴倒置的實現。
假設:
現在你需要實現一個麵包店,你第一件想到的事情是什麼?
我想到的是一個麵包店,裡面有很多具體的麵包。
例如:法棍麵包、全麥麵包、白麵包、牛角麵包、蕎麥麵包、法式麵包、甜甜圈麵包、裸麥麵包。
傳統依賴關係:
麵包店就是上層模組,麵包是下層模組。如圖:
麵包店(Bakery)直接依賴於具體的麵包型別(FrenchBaguette 和 WholeWheatBread),這是傳統的依賴關係。
當增加底層模組(麵包型別)時,對高層模組(麵包店)有何影響呢。
class Bakery {
private FrenchBaguette frenchBaguette;
private WholeWheatBread wholeWheatBread;
public Bakery() {
frenchBaguette = new FrenchBaguette();
wholeWheatBread = new WholeWheatBread();
// 初始化具體的麵包型別
}
public void serveBread() {
frenchBaguette.serve();
wholeWheatBread.serve();
// 提供其他具體面包型別
}
}
class FrenchBaguette {
public void serve() {
System.out.println("法棍麵包供應中");
}
}
class WholeWheatBread {
public void serve() {
System.out.println("全麥麵包供應中");
}
}
// 假設現在需要新增一種新的麵包型別,例如牛角麵包
class Croissant {
public void serve() {
System.out.println("牛角麵包供應中");
}
}
public class Main {
public static void main(String[] args) {
Bakery bakery = new Bakery();
bakery.serveBread();
// 現在需要新增新的麵包型別(牛角麵包)
Croissant croissant = new Croissant();
croissant.serve();
// 這裡需要手動修改Bakery類,將新的麵包型別整合進去
}
}
如果要新增新的麵包型別,例如 Croissant
,就需要修改 Bakery
類的程式碼,將新的麵包型別整合進去。
顯然,這種方式不夠靈活,增加了維護成本和程式碼的脆弱性。
依賴倒置:
我們不希望讓麵包店理會這些具體類,於是,重新設計麵包店:
建立一個抽象的麵包介面,讓麵包店依賴於這個抽象介面,不再依賴於具體的麵包種類。
既然法棍麵包、牛角麵包、白麵包等都是麵包,就讓它們共享一個麵包介面,抽象化一個麵包類。
如圖所示:
麵包店是高層模組,麵包類是抽象介面,而各種具體的麵包是底層模組。
現在,我們需要增加新的麵包型別(底層模組)。
// 麵包介面,作為高層模組和底層模組之間的抽象
interface Bread {
void serve();
}
// 具體面包類實現麵包介面,作為底層模組
class FrenchBaguette implements Bread {
public void serve() {
System.out.println("法棍麵包供應中");
}
}
class WholeWheatBread implements Bread {
public void serve() {
System.out.println("全麥麵包供應中");
}
}
// 假設需要新增一種新的麵包型別,例如牛角麵包
class Croissant implements Bread {
public void serve() {
System.out.println("牛角麵包供應中");
}
}
// 高層模組,麵包店
class Bakery {
private Bread bread;
public Bakery(Bread bread) {
this.bread = bread;
}
public void serveBread() {
bread.serve();
}
}
public class Main {
public static void main(String[] args) {
// 建立麵包店並提供不同型別的麵包
Bread frenchBaguette = new FrenchBaguette();
Bread wholeWheatBread = new WholeWheatBread();
Bakery bakery1 = new Bakery(frenchBaguette);
bakery1.serveBread();
Bakery bakery2 = new Bakery(wholeWheatBread);
bakery2.serveBread();
// 新增的麵包型別(牛角麵包)不會影響麵包店
Bread croissant = new Croissant();
Bakery bakery3 = new Bakery(croissant);
bakery3.serveBread();
}
}
麵包店(Bakery
)依賴於抽象的 Bread
介面,而不依賴於具體的麵包型別。
當需要新增一種麵包型別(例如Croissant
)時,不會對高層模組(Bakery
)產生影響,因為高層模組依賴於抽象介面。
對於具體的實現類我們不管,只要介面的行為不發生變化,增加新的麵包類後,上層服務不用做任何的修改。
這樣的設計降低了層與層之間的耦合,能很好地適應需求的變化,從而提高了系統的可擴充套件性和可維護性。
依賴倒置原則透過抽象(介面或抽象類),讓各個類或模組的實現彼此獨立,不互相影響,實現模組間的松耦合。
依賴倒置原則的核心思想是:高層模組不應依賴於低層模組,兩者都應該依賴於抽象。抽象不應該依賴於細節,細節應該依賴於抽象。
遵循依賴倒置原則,透過降低層與層之間的耦合,可以很好地適應需求的變化,提高了系統的可擴充套件性和可維護性。
建議收藏備用,划走就再也找不到了。
依賴倒置是良好架構設計的基石,社/校招面試也常問,必知必會非常重要。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024922/viewspace-2992214/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 3 分鐘吃透開閉原則,架構設計築基必知必會架構
- 必知必會的設計原則——介面隔離原則
- 嘻哈說:設計模式之依賴倒置原則設計模式
- SOLDI原則之DIP:依賴倒置原則
- 什麼是依賴倒置原則
- 依賴倒置原則(Dependence Inversion Principle)
- 面象物件設計6大原則之五:依賴倒置原則物件
- 完整的PHP依賴倒置原則例程PHP
- python3 依賴倒置原則示例Python
- 一張圖徹底搞懂Spring迴圈依賴Spring
- Laravel深入學習12 – 依賴倒置原則Laravel
- 設計模式例項講解 - 依賴倒置設計模式
- 依賴倒置原則的基本用法和介紹
- 設計原則-依賴反轉原則
- 設計原則之【依賴反轉原則】
- 徹底清理依賴:
- 軟體設計原則—依賴倒轉原則
- 阿里P7架構師告訴你Java架構師必須知道的 6 大設計原則阿里架構Java
- 【架構視角】一篇文章帶你徹底吃透Spring架構Spring
- 高頻面試題:一張圖徹底搞懂Spring迴圈依賴面試題Spring
- 7 大設計原則總結篇(41張圖解、2萬多字、非常詳細)圖解
- 設計模式必備知識點---六大設計原則設計模式
- ElasticSearch必知必會-進階篇Elasticsearch
- 15 張圖,瞭解一下 TCP/IP 必知也必會的 10 個問題TCP
- Java必知必會之註解Java
- SOLID架構設計原則Solid架構
- bom和dom就看這張圖
- 學習MyBatis必知必會(7)~註解開發、動態SQLMyBatisSQL
- Flutter佈局詳解,必知必會Flutter
- 達夢資料庫必知必會-DCA篇資料庫
- MySQL 必知必會MySql
- Linux必會必知Linux
- git必會必知Git
- Redis 必知必會Redis
- ThreadLocal必知必會thread
- Activity 必知必會
- JSON 必知必會JSON
- HashMap必知必會HashMap