監(jiān)理公司管理系統(tǒng) | 工程企業(yè)管理系統(tǒng) | OA系統(tǒng) | ERP系統(tǒng) | 造價(jià)咨詢(xún)管理系統(tǒng) | 工程設(shè)計(jì)管理系統(tǒng) | 簽約案例 | 購(gòu)買(mǎi)價(jià)格 | 在線試用 | 手機(jī)APP | 產(chǎn)品資料
X 關(guān)閉

OO設(shè)計(jì)原則 -- Dependency Inversion Principle:OO設(shè)計(jì)的 DIP依賴(lài)倒置原則

申請(qǐng)免費(fèi)試用、咨詢(xún)電話:400-8352-114

 

依賴(lài)倒置原則的2個(gè)重要方針

A. High level modules should not depend upon low level modules. Both shoulddepend upon abstractions.

高層模塊不應(yīng)該依賴(lài)于低層模塊,二者都應(yīng)該依賴(lài)于抽象
B. Abstractions should not depend upon details. Details should depend uponabstractions.
抽象不應(yīng)該依賴(lài)于細(xì)節(jié),細(xì)節(jié)應(yīng)該依賴(lài)于抽象

 

概念解說(shuō):

依賴(lài):在程序設(shè)計(jì)中,如果一個(gè)模塊a使用/調(diào)用了另一個(gè)模塊b,我們稱(chēng)模塊a依賴(lài)模塊b。

低層模塊:往往在一個(gè)應(yīng)用程序中,我們有一些低層次的類(lèi),這些類(lèi)實(shí)現(xiàn)了一些

基本的或初級(jí)的操作,我們稱(chēng)之為低層模塊;

高層模塊:另外有一些高層次的類(lèi),這些類(lèi)封裝了某些復(fù)雜的邏輯,并且依賴(lài)于

低層次的類(lèi),這些類(lèi)我們稱(chēng)之為高層模塊。

 

我們現(xiàn)在來(lái)看看依賴(lài)有幾種,依賴(lài)也就是耦合,分為下面三種:

----- 零耦合(Nil Coupling)關(guān)系,兩個(gè)類(lèi)沒(méi)有依賴(lài)關(guān)系,那就是零耦合。

----- 具體耦合(Concrete Coupling)關(guān)系,兩個(gè)具體的類(lèi)之間有依賴(lài)關(guān)系,

那么就是具體耦合關(guān)系,如果一個(gè)具體類(lèi)直接引用另外一個(gè)具體類(lèi)就會(huì)發(fā)

生這種關(guān)系。

-----抽象耦合(Abstract Coupling)關(guān)系,這種關(guān)系發(fā)生在一個(gè)具體類(lèi)和一個(gè)抽

象類(lèi)之間,這樣就使必須發(fā)生關(guān)系的類(lèi)之間保持最大的靈活性。


為什么叫做依賴(lài)倒置(DependencyInversion)呢?
面向?qū)ο蟪绦蛟O(shè)計(jì)相對(duì)于面向過(guò)程(結(jié)構(gòu)化)程序設(shè)計(jì)而言,依賴(lài)關(guān)系被倒置了。因?yàn)閭鹘y(tǒng)的結(jié)構(gòu)化程序設(shè)計(jì)中,高層模塊總是依賴(lài)于低層模塊。

 

依賴(lài)倒置(Dependence InversionPrinciple)原則講的是:要依賴(lài)于抽象,不要依賴(lài)于具體。

簡(jiǎn)單的說(shuō),依賴(lài)倒置原則要求客戶(hù)端依賴(lài)于抽象耦合。原則表述:

抽象不應(yīng)當(dāng)依賴(lài)于細(xì)節(jié);細(xì)節(jié)應(yīng)當(dāng)依賴(lài)于抽象;

要針對(duì)接口編程,不針對(duì)實(shí)現(xiàn)編程。

 

問(wèn)題的提出

Robert C. Martin氏在原文中給出了“Bad Design”的定義:
1. It is hard to change because every change affects too many other parts ofthe system.(Rigidity)
系統(tǒng)很難改變,因?yàn)槊總€(gè)改變都會(huì)影響其他很多部分。
2. When you make a change, unexpected parts of the system break. (Fragility)
當(dāng)你對(duì)某地方做一修改,系統(tǒng)的看似無(wú)關(guān)的其他部分都不工作了。
3. It is hard to reuse in another application because it cannot be disentangledfrom the current application. (Immobility)
系統(tǒng)很難被另外一個(gè)應(yīng)用重用,因?yàn)槟愫茈y將要重用的部分從系統(tǒng)中分離開(kāi)來(lái)。

導(dǎo)致“Bad Design”的很大原因是“高層模塊”過(guò)分依賴(lài)“低層模塊”。
一個(gè)良好的設(shè)計(jì)應(yīng)該是系統(tǒng)的每一部分都是可替換的。
如果“高層模塊”過(guò)分依賴(lài)“低層模塊”:

一方面一旦“低層模塊”需要替換或者修改,“高層模塊”將受到影響;

另一方面,高層模塊很難可以重用。

比如,一個(gè)Copy模塊,需要把來(lái)自Keyboard的輸入復(fù)制到Print,

即使對(duì)Keyboard和Print的封裝已經(jīng)做得非常好,但如果Copy模塊里直接使用Keyboard與Print,

Copy任很難被其他應(yīng)用環(huán)境(比如需要輸出到磁盤(pán)時(shí))重用。

問(wèn)題的解決:

為了解決上述問(wèn)題,Robert C. Martin氏提出了OO設(shè)計(jì)的Dependency Inversion Principle (DIP) 原則。

DIP給出了一個(gè)解決方案:

在高層模塊與低層模塊之間,引入一個(gè)抽象接口層。


High Level Classes(高層模塊)  -->

Abstraction Layer(抽象接口層) -->

Low Level Classes(低層模塊)


抽象接口是對(duì)低層模塊的抽象,低層模塊繼承或?qū)崿F(xiàn)該抽象接口。
這樣,高層模塊不直接依賴(lài)低層模塊,高層模塊與低層模塊都依賴(lài)抽象接口層。
當(dāng)然,抽象也不依賴(lài)低層模塊的實(shí)現(xiàn)細(xì)節(jié),低層模塊依賴(lài)(繼承或?qū)崿F(xiàn))抽象定義。

Robert C. Martin氏給出的DIP方案的類(lèi)的結(jié)構(gòu)圖:


PolicyLayer -->

MechanismInterface(abstract) -->

MechanismLayer -->

UtilityInterface(abstract) -->

UtilityLayer


類(lèi)與類(lèi)之間都通過(guò)Abstract Layer來(lái)組合關(guān)系。

 

 實(shí)例說(shuō)明DIP

反面例子:


缺點(diǎn):耦合太緊密,Light發(fā)生變化將影響ToggleSwitch。

解決辦法一:
將Light作成Abstract,然后具體類(lèi)繼承自Light。


優(yōu)點(diǎn):ToggleSwitch依賴(lài)于抽象類(lèi)Light,具有更高的穩(wěn)定性,而B(niǎo)ulbLight與TubeLight繼承自Light,可以根 據(jù)"開(kāi)放-封閉"原則進(jìn)行擴(kuò)展。只要Light不發(fā)生變化,BulbLight與TubeLight的變化就不會(huì)波及ToggleSwitch。

缺點(diǎn):如果用ToggleSwitch控制一臺(tái)電視就很困難了??偛荒茏孴V繼承自Light吧。

解決方法二:



優(yōu)點(diǎn):更為通用、更為穩(wěn)定。

 

總結(jié)

 

 DIP要求客戶(hù)端依賴(lài)于抽象耦合,抽象不應(yīng)當(dāng)依賴(lài)于細(xì)節(jié),細(xì)節(jié)應(yīng)當(dāng)依賴(lài)于抽象(Abstractionsshould not depend upon details. Details should depend upon abstractions),這 個(gè)原則的另外一個(gè)表述就是"四人團(tuán)"強(qiáng)調(diào)的那個(gè):要針對(duì)接口編程,不要對(duì)實(shí)現(xiàn)編程(Program to aninterface, not an implementation),程序在需要引用一個(gè)對(duì)象時(shí),應(yīng)當(dāng)盡可能的使用抽象類(lèi)型作為變量的靜態(tài)類(lèi)型,這就是針對(duì)接口編程的含義。DIP是達(dá)到"開(kāi)-閉"原則的途徑。

要做到DIP,用抽象方式耦合是關(guān)鍵。由于一個(gè)抽象耦合總要涉及具體類(lèi)從抽象類(lèi)繼承。并且需要保證在任何引用到某類(lèi)的地方都可以改換成其子類(lèi),因此,LSP是DIP的基礎(chǔ)。DIP是OOD的核心原則,設(shè)計(jì)模式的研究和應(yīng)用都是用它作為指導(dǎo)原則的。DIP雖然強(qiáng)大,但是也很難實(shí)現(xiàn)。另外DIP是假定 所有的具體類(lèi)都會(huì)變化,這也不是全對(duì),有些具體類(lèi)就相當(dāng)穩(wěn)定。使用這個(gè)類(lèi)的客戶(hù)端就完全可以依賴(lài)這個(gè)具體類(lèi)而不用再弄一個(gè)抽象類(lèi)。





發(fā)布:2007-04-17 09:47    編輯:泛普軟件 · xiaona    [打印此頁(yè)]    [關(guān)閉]
相關(guān)文章:

泛普商業(yè)銷(xiāo)售管理軟件其他應(yīng)用

外貿(mào)行業(yè) 外貿(mào)管理軟件 服裝銷(xiāo)售管理軟件 零售管理系統(tǒng) 汽車(chē)銷(xiāo)售管理系統(tǒng) 售后管理系統(tǒng) 電話銷(xiāo)售管理系統(tǒng) 電腦銷(xiāo)售管理軟件 門(mén)店銷(xiāo)售管理軟件 分銷(xiāo)管理系統(tǒng) 商業(yè)銷(xiāo)售管理軟件 行銷(xiāo)支持管理系統(tǒng) 商品銷(xiāo)售管理系統(tǒng)