抽象不應(yīng)該依賴細(xì)節(jié)褐着,細(xì)節(jié)應(yīng)該依賴于抽象判莉。高層模塊不應(yīng)該依賴于底層模塊豆挽,都應(yīng)該依賴的抽象。
依賴反轉(zhuǎn)原則主要想告訴我們的是券盅,如果想設(shè)計(jì)一個(gè)靈活的系統(tǒng)帮哈,在源代碼層次的依賴關(guān)系中就應(yīng)該多引用抽象類型舟肉,而非具體類型嗅绰。
- 穩(wěn)定的抽象層
每次修改抽象層的時(shí)候,一定也會(huì)去修改對(duì)應(yīng)的具體實(shí)現(xiàn)差油。但是反過(guò)來(lái)泳炉,當(dāng)我們修改具體的實(shí)現(xiàn)的時(shí)候憾筏,卻很少需要去修改相應(yīng)的抽象接口。所以接口比實(shí)現(xiàn)更穩(wěn)定花鹅。
依賴守則
應(yīng)在代碼中多使用抽象接口氧腰,盡量避免使用那些多變的具體實(shí)現(xiàn)類。
抽象工廠設(shè)計(jì)模式
不要在具體實(shí)現(xiàn)類上創(chuàng)建衍生類
面向?qū)ο蟮木幊讨信偎啵^承關(guān)系是所有以前源代碼依賴關(guān)系中最強(qiáng)的古拴、最難被修改的,所以我們對(duì)繼承的使用應(yīng)該格外小心之景。
不要覆蓋包含具體實(shí)現(xiàn)的函數(shù)
調(diào)用包含具體實(shí)現(xiàn)的函數(shù)通常意味著引入了源代碼級(jí)別的依賴斤富。即使覆蓋了這些函數(shù),也無(wú)法消除這些依賴關(guān)系锻狗÷Γ控制依賴關(guān)系的唯一辦法就是使用抽象函數(shù)焕参,然后再為該函數(shù)提供多種具體實(shí)現(xiàn)
應(yīng)避免在代碼中寫(xiě)入與任何具體實(shí)現(xiàn)相關(guān)的名字,或者是其他容易變動(dòng)的事務(wù)的名字油额。
創(chuàng)建對(duì)象為例
我們必須對(duì)那些易變對(duì)象的創(chuàng)建過(guò)程做一些特殊處理叠纷,創(chuàng)建對(duì)象的操作都避免不了需要在源代碼層次上依賴對(duì)象的具體實(shí)現(xiàn)。在大部分面向?qū)ο缶幊陶Z(yǔ)言中潦嘶,人們會(huì)選擇用抽象工廠模式來(lái)解決這個(gè)源代碼依賴的問(wèn)題涩嚣。
Application類通過(guò)Service接口來(lái)使用ConcreteImpl類的。然而Application類還是必須要構(gòu)造ConcreteImpl類實(shí)例掂僵。為了避免在代碼層次上對(duì)引入ConcreteImpl類具體實(shí)現(xiàn)的依賴航厚,現(xiàn)在讓Application類去調(diào)用ServiceFactory接口的makeSvc方法。這個(gè)方法就由ServiceFactoryImpl類具體提供锰蓬,它是ServiceFactory的一個(gè)衍生類幔睬。ServiceFactoryImpl類中makeSvc的具體實(shí)現(xiàn)就是提供一個(gè)ConcreteImpl類的實(shí)例。
圖中那條曲線表示軟件架構(gòu)中抽象層與具體實(shí)現(xiàn)層的邊界芹扭。這里所有跨越這條邊界的代碼級(jí)別的依賴關(guān)系都應(yīng)該是單向麻顶,即具體實(shí)現(xiàn)層依賴抽象層。
這條曲線將整個(gè)系統(tǒng)劃分為兩部分組件:抽象接口與其具體實(shí)現(xiàn)舱卡。抽象接口組件中包含了應(yīng)用的所有高階業(yè)務(wù)規(guī)則辅肾,而具體實(shí)現(xiàn)組件中則包含了所有這些業(yè)務(wù)規(guī)則需要做的具體操作及其相關(guān)細(xì)節(jié)信息。
這里控制跨越架構(gòu)邊界的方向與源代碼依賴關(guān)系跨越該邊界的方向正好相反轮锥,源代碼依賴方向永遠(yuǎn)是控制流方向的反轉(zhuǎn)矫钓。