DesignPattern系列__03依賴倒置原則

依賴倒置原則(Dependence Inversion Priiciple,DIP)

介紹

High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Detatils should depend upon abstractions.
翻譯過來有是三個(gè)意思:

1.高層模塊不應(yīng)該依賴底層模塊柴我,兩者都應(yīng)該依賴其抽象骨坑。

2.抽象不應(yīng)該依賴細(xì)節(jié)羞海。

3.細(xì)節(jié)應(yīng)該依賴抽象厘灼。

在Java中够坐,表現(xiàn)就是:

1.模塊間的依賴通過抽象發(fā)生摇邦,實(shí)現(xiàn)類之間不應(yīng)該發(fā)生直接的依賴關(guān)機(jī)汞窗,其依賴關(guān)系應(yīng)該是用過接口或者抽象類產(chǎn)生的;

2.接口或者抽象類不應(yīng)該依賴實(shí)現(xiàn)類刊苍;

3.實(shí)現(xiàn)類應(yīng)該依賴接口或者抽象類靖苇。

依賴倒置原則的設(shè)計(jì)理念是:相較于實(shí)習(xí)類具有多變性,抽象要穩(wěn)定的多班缰。框架的設(shè)計(jì)應(yīng)該基于抽象悼枢,這樣子埠忘,能提高項(xiàng)目的穩(wěn)定性。
在框架中馒索,抽象的作用是用來制定規(guī)范莹妒,具體的細(xì)節(jié)應(yīng)該交給實(shí)現(xiàn)類。

應(yīng)用實(shí)例

有一個(gè)司機(jī)類對(duì)象張三(zs)绰上,具有drive方法來駕駛汽車旨怠。

public class Dependence1 {
    public static void main(String[] args) {
        Driver zs = new Driver();
        Benz benz = new Benz();
        zs.drive(benz);
    }
}

class Driver {
    public void drive(Benz benz) {
        benz.run();
    }
}

class Benz {
    public void run() {
        System.out.println("奔馳汽車發(fā)動(dòng)...");
    }
}

//經(jīng)過艱苦奮斗,張三同志買了一輛寶馬汽車
class BMW {
    public void run() {
        System.out.println("寶馬汽車發(fā)動(dòng)...");
    }
}

目前為止蜈块,看上去很美好鉴腻,正常的功能也實(shí)現(xiàn)了迷扇;但是,因?yàn)檫@個(gè)功能是基于具體的實(shí)現(xiàn)類Benz實(shí)現(xiàn)的爽哎,這就為后來的擴(kuò)展帶來了麻煩:比如張三同志艱苦奮斗蜓席,又買了一輛寶馬(BMW),但是根據(jù)Driver類的drive方法课锌,張三同志不能駕駛新買的寶馬汽車厨内。這就是很嚴(yán)重的邏輯了:只要是有了駕照,奔馳和寶馬應(yīng)該都能駕駛渺贤。

改進(jìn)措施:

很明顯雏胃,司機(jī)類中的drive方法不應(yīng)該依賴于一種具體品牌的汽車,而因該是汽車的泛指志鞍。所以瞭亮,新建兩個(gè)接口:
IDriver和ICar,分別定義了司機(jī)和汽車的職能述雾,汽車就是駕駛汽車街州。具體的代碼如下:

public class Dependence2 {
    public static void main(String[] args) {
        IDriver zs = new Driver();
        ICar benz = new Benz();
        zs.drive(benz);
        ICar bmw = new BMW();
        zs.drive(bmw);
    }
}

interface ICar {
    //是汽車都應(yīng)該具備的功能
    public void run();
}

class Benz implements ICar {
    @Override
    public void run() {
        System.out.println("奔馳汽車發(fā)動(dòng)...");
    }
}

class BMW implements ICar {
    @Override
    public void run() {
        System.out.println("寶馬汽車發(fā)動(dòng)...");
    }
}

interface IDriver {
    //是司機(jī)就應(yīng)該會(huì)開車,不管是什么車
    public void drive(ICar iCar);
}

class Driver implements IDriver {
    @Override
    public void drive(ICar iCar) {
        iCar.run();
    }
}

在demo中玻孟,類Dependence2 作為高層模塊唆缴,它對(duì)底層模塊的依賴建立在抽象上;司機(jī)張三的表面類型時(shí)IDriver黍翎,Benz和BMW的表面類型是ICar面徽,這樣做,在擴(kuò)展業(yè)務(wù)邏輯(比如新增一輛汽車Mini)時(shí)匣掸,只需修改業(yè)務(wù)場景類(高層模塊)趟紊,對(duì)底層模塊如Driver和Benz等沒有影響。

依賴的三種形式

依賴的形式有三種:接口依賴碰酝、setter方法依賴和構(gòu)造器依賴霎匈。具體介紹如下:

1.接口依賴

顧名思義,就是通過實(shí)現(xiàn)接口的方式注入依賴送爸,代碼詳見上面的改進(jìn)措施铛嘱。

2.setter方法依賴

在抽象中定義setter方法,就是所謂的setter方法依賴袭厂。
demo如下:

interface IDriver {
    //setter方式注入
    public void setICar(ICar iCar);

}

class Driver implements IDriver {
    private ICar iCar;

    @Override
    public void setICar(ICar iCar) {
        this.iCar = iCar;
    }

}

3.構(gòu)造器依賴

這個(gè)也比較好理解墨吓,就是將ICar的具體類型,通過構(gòu)造器傳給Driver:

class Driver implements IDriver {
    private ICar iCar;
    
    public Driver(ICar iCar) {
        this.iCar =iCar;    
    }
}

注意事項(xiàng)和細(xì)節(jié)

在項(xiàng)目中纹磺,底層模塊的類都應(yīng)該有抽象類或者接口帖烘,或者兩者都有;
變量的聲明應(yīng)該是抽象類型橄杨,有利于提高項(xiàng)目的穩(wěn)定性秘症;
任何類都不應(yīng)該從具體類派生照卦;
盡量不要重寫積累的方法,要結(jié)合“里氏替換原則”使用历极。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末窄瘟,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子趟卸,更是在濱河造成了極大的恐慌蹄葱,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锄列,死亡現(xiàn)場離奇詭異图云,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)邻邮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門竣况,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人筒严,你說我怎么就攤上這事丹泉。” “怎么了鸭蛙?”我有些...
    開封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵摹恨,是天一觀的道長。 經(jīng)常有香客問我娶视,道長晒哄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任肪获,我火速辦了婚禮寝凌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘孝赫。我一直安慰自己较木,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開白布青柄。 她就那樣靜靜地躺著劫映,像睡著了一般。 火紅的嫁衣襯著肌膚如雪刹前。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天雌桑,我揣著相機(jī)與錄音喇喉,去河邊找鬼。 笑死校坑,一個(gè)胖子當(dāng)著我的面吹牛拣技,可吹牛的內(nèi)容都是我干的千诬。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼膏斤,長吁一口氣:“原來是場噩夢啊……” “哼徐绑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起莫辨,我...
    開封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤傲茄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后沮榜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盘榨,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年蟆融,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了草巡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡型酥,死狀恐怖山憨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情弥喉,我是刑警寧澤郁竟,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站档桃,受9級(jí)特大地震影響枪孩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜藻肄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一蔑舞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧嘹屯,春花似錦攻询、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至婆翔,卻和暖如春拯杠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背啃奴。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來泰國打工潭陪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓依溯,卻偏偏與公主長得像老厌,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子黎炉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容