設(shè)計模式六大原則(3):依賴倒置原則
來源:易賢網(wǎng) 閱讀:1048 次 日期:2015-04-02 12:53:47
溫馨提示:易賢網(wǎng)小編為您整理了“設(shè)計模式六大原則(3):依賴倒置原則”,方便廣大網(wǎng)友查閱!

定義:高層模塊不應(yīng)該依賴低層模塊,二者都應(yīng)該依賴其抽象;抽象不應(yīng)該依賴細節(jié);細節(jié)應(yīng)該依賴抽象。

問題由來:類A直接依賴類B,假如要將類A改為依賴類C,則必須通過修改類A的代碼來達成。這種場景下,類A一般是高層模塊,負責(zé)復(fù)雜的業(yè)務(wù)邏輯;類B和類C是低層模塊,負責(zé)基本的原子操作;假如修改類A,會給程序帶來不必要的風(fēng)險。

解決方案:將類A修改為依賴接口I,類B和類C各自實現(xiàn)接口I,類A通過接口I間接與類B或者類C發(fā)生聯(lián)系,則會大大降低修改類A的幾率。

依賴倒置原則基于這樣一個事實:相對于細節(jié)的多變性,抽象的東西要穩(wěn)定的多。以抽象為基礎(chǔ)搭建起來的架構(gòu)比以細節(jié)為基礎(chǔ)搭建起來的架構(gòu)要穩(wěn)定的多。在java中,抽象指的是接口或者抽象類,細節(jié)就是具體的實現(xiàn)類,使用接口或者抽象類的目的是制定好規(guī)范和契約,而不去涉及任何具體的操作,把展現(xiàn)細節(jié)的任務(wù)交給他們的實現(xiàn)類去完成。

依賴倒置原則的核心思想是面向接口編程,我們依舊用一個例子來說明面向接口編程比相對于面向?qū)崿F(xiàn)編程好在什么地方。場景是這樣的,母親給孩子講故事,只要給她一本書,她就可以照著書給孩子講故事了。代碼如下:

class Book{

public String getContent(){

return "很久很久以前有一個阿拉伯的故事……";

}

}

class Mother{

public void narrate(Book book){

System.out.println("媽媽開始講故事");

System.out.println(book.getContent());

}

}

public class Client{

public static void main(String[] args){

Mother mother = new Mother();

mother.narrate(new Book());

}

}

運行結(jié)果:

媽媽開始講故事

很久很久以前有一個阿拉伯的故事……

運行良好,假如有一天,需求變成這樣:不是給書而是給一份報紙,讓這位母親講一下報紙上的故事,報紙的代碼如下:

class Newspaper{

public String getContent(){

return "林書豪38+7領(lǐng)導(dǎo)尼克斯擊敗湖人……";

}

}

這位母親卻辦不到,因為她居然不會讀報紙上的故事,這太荒唐了,只是將書換成報紙,居然必須要修改Mother才能讀。假如以后需求換成雜志呢?換成網(wǎng)頁呢?還要不斷地修改Mother,這顯然不是好的設(shè)計。原因就是Mother與Book之間的耦合性太高了,必須降低他們之間的耦合度才行。

我們引入一個抽象的接口IReader。讀物,只要是帶字的都屬于讀物:

interface IReader{

public String getContent();

}

Mother類與接口IReader發(fā)生依賴關(guān)系,而Book和Newspaper都屬于讀物的范疇,他們各自都去實現(xiàn)IReader接口,這樣就符合依賴倒置原則了,代碼修改為:

class Newspaper implements IReader {

public String getContent(){

return "林書豪17+9助尼克斯擊敗老鷹……";

}

}

class Book implements IReader{

public String getContent(){

return "很久很久以前有一個阿拉伯的故事……";

}

}

class Mother{

public void narrate(IReader reader){

System.out.println("媽媽開始講故事");

System.out.println(reader.getContent());

}

}

public class Client{

public static void main(String[] args){

Mother mother = new Mother();

mother.narrate(new Book());

mother.narrate(new Newspaper());

}

}

運行結(jié)果:

媽媽開始講故事

很久很久以前有一個阿拉伯的故事……

媽媽開始講故事

林書豪17+9助尼克斯擊敗老鷹……

這樣修改后,無論以后怎樣擴展Client類,都不需要再修改Mother類了。這只是一個簡單的例子,實際情況中,代表高層模塊的Mother類將負責(zé)完成主要的業(yè)務(wù)邏輯,一旦需要對它進行修改,引入錯誤的風(fēng)險極大。所以遵循依賴倒置原則可以降低類之間的耦合性,提高系統(tǒng)的穩(wěn)定性,降低修改程序造成的風(fēng)險。

采用依賴倒置原則給多人并行開發(fā)帶來了極大的便利,比如上例中,原本Mother類與Book類直接耦合時,Mother類必須等Book類編碼完成后才可以進行編碼,因為Mother類依賴于Book類。修改后的程序則可以同時開工,互不影響,因為Mother與Book類一點關(guān)系也沒有。參與協(xié)作開發(fā)的人越多、項目越龐大,采用依賴導(dǎo)致原則的意義就越重大。現(xiàn)在很流行的TDD開發(fā)模式就是依賴倒置原則最成功的應(yīng)用。

傳遞依賴關(guān)系有三種方式,以上的例子中使用的方法是接口傳遞,另外還有兩種傳遞方式:構(gòu)造方法傳遞和setter方法傳遞,相信用過Spring框架的,對依賴的傳遞方式一定不會陌生。

在實際編程中,我們一般需要做到如下3點:

低層模塊盡量都要有抽象類或接口,或者兩者都有。

變量的聲明類型盡量是抽象類或接口。

使用繼承時遵循里氏替換原則。

依賴倒置原則的核心就是要我們面向接口編程,理解了面向接口編程,也就理解了依賴倒置。

更多信息請查看IT技術(shù)專欄

更多信息請查看技術(shù)文章
易賢網(wǎng)手機網(wǎng)站地址:設(shè)計模式六大原則(3):依賴倒置原則

2025國考·省考課程試聽報名

  • 報班類型
  • 姓名
  • 手機號
  • 驗證碼
關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 加入群交流 | 手機站點 | 投訴建議
工業(yè)和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網(wǎng)安備53010202001879號 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號
聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關(guān)注公眾號:hfpxwx
咨詢QQ:526150442(9:00—18:00)版權(quán)所有:易賢網(wǎng)