版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、依賴和耦合關系 1、依賴和耦合( Dependency and Coupling ) ( 1)什么是依賴 Rose 的幫助文檔上是這樣定義“依賴”關系的: “依賴描述了兩個模型元素之間的關系,如果被依賴 的模型元素發(fā)生變化就會影響到另一個模型元素。典型的,在類圖上,依賴關系表明客戶類的操作會調(diào)用 服務器類的操作。 ” ( 2)什么是耦合 Martin Fowler 在 Reducing Coupling 一文中這樣描述耦合: “如果改變程序的一個模塊要求另一個 模塊同時發(fā)生變化,就認為這兩個模塊發(fā)生了耦合。 ” Fowler 2001 從上面的定義可以看出:如果模塊 A 調(diào)用模塊 B 提供的方
2、法,或訪問模塊 B 中的某些數(shù)據(jù)成員(當 然,在面向對象開發(fā)中一般不提倡這樣做) ,我們就認為模塊 A 依賴于模塊 B ,模塊 A 和模塊 B 之間發(fā)生 了耦合。 耦合是依賴的同義詞,被定義為“兩個元素之間的一種關系,其中一個元素變化,導致另一個元素變 化”。抽象耦合被定義為“若類 A 維護一個指向抽象類 B 的引用,則稱類 A 抽象耦合于 B”。 2、依賴是不可避免的 ( 1)“分而治之”的問題處理方法 對于復雜的系統(tǒng),我們常常采用它劃分成多個模塊,這樣將能夠有效地控制模塊的復雜度,使每個模 塊都易于理解和維護。 ( 2)“分而治之”的結果是產(chǎn)生依賴關系 一旦我們采用 “分而治之”的處理方法
3、后, 模塊之間就必須以某種方式交換信息,也就是必然要 發(fā)生某種耦合關系。 如果某個模塊和其它模塊沒有任何關聯(lián)(哪怕只是潛在的或隱含的依賴關系) ,我們就幾乎可以 斷定,該模塊不屬于此軟件系統(tǒng),應該從系統(tǒng)中剔除。 如果所有模塊之間都沒有任何耦合關系,其結果必然是:整個軟件不過是多個互不相干的系統(tǒng)的 簡單堆積, 對每個系統(tǒng)而言, 所有功能還是要在一個模塊中實現(xiàn), 這等于沒有做任何模塊的分解。 ( 3)依賴是不可避免的 因此,模塊之間必定會有這樣或那樣的依賴關系, 我們永遠也不要幻想消除所有的依賴(耦合關系) 。 我們在類的設計時,應該首先考慮的是該類應該盡可能依賴不經(jīng)常變化的“目標” 比如,系統(tǒng)的
4、 API 庫或者框架中的組件 試圖令具體的、易變的模塊依賴于抽象的、穩(wěn)定的模塊的基本原則。 在 Java 中,表示字符串的是具體內(nèi) String 。該類是穩(wěn)定的,也就是說,它不太會改變。因此,直接依 賴于它不會造成損害。 既然變化不可避免,我們所能做的就是處理好依賴關系,將變化造成的影響的波及范圍盡量減小。 ( 4)我們所追求的是盡可能降低過強的耦合關系 “依賴”是和“變化”緊密聯(lián)系在一起的概念。由于依賴關系的存在,變化在某處發(fā)生時,影響會波 及開去,造成很多修改工作,這就是依賴的危害。 因為,過強的耦合關系(如一個模塊的變化會造成一個或多個其他模塊也同時發(fā)生變化的依賴關 系)會對軟件系統(tǒng)的質
5、量造成很大的危害。 特別是當需求發(fā)生變化時,代碼的維護成本將非常高。所以,我們必須想盡辦法來控制和消解不 必要的耦合,特別是那種會導致其它模塊發(fā)生不可控變化的依賴關系。 ( 5)如何達到 采用什么的策略或者方法 依賴倒置、控制反轉、依賴注入等原則。 3、依賴倒置( DIPDependency Inversion Principle ) ( 1)什么是依賴倒置 將依賴關系倒置為依賴接口 依賴倒置原則就是建立在抽象接口的基礎上的。 Robert Martin 這樣描述依賴倒置原則 Martin 1996 : 上層模塊不應該依賴于下層模塊,它們共同依賴于一個抽象。 也就是“系統(tǒng)的核心邏輯”不依賴于“
6、具體的實現(xiàn)細 抽象不能依賴于具體,具體依賴于抽象 節(jié)”。 依賴性倒置原則形式化了抽象耦合的概念,明確表述了應該“依賴于抽象類,不要依賴于具體類” (2)如何達到依賴倒置的效果 為了消解兩個模塊間的依賴關系,應該在兩個模塊之間定義一個抽象接口,上層模塊調(diào)用抽象接口定 義的方法,下層模塊實現(xiàn)該接口。 針對接口編程遵守上述原則,從而在很大程度上阻止了變化波及范圍的擴大,有效地隔離了變化,有 助于增強系統(tǒng)的可重用性和可擴展性。 (3)為什么要依賴接口 因為抽象是相對穩(wěn)定的或者是相對變化不頻繁的,而具體是易變的 因此,要使我們的設計具有很大的靈活性,就需要做到大家都依賴于抽象的東西,而利用抽象隔離具 體
7、類之間的關系,這樣使得“具體”的任何改動都可以在局部范圍內(nèi)實現(xiàn),而不影響其它的結構。 比如,一個10系統(tǒng)它必然就有 READ/WRITE這兩個抽象,至于具體是磁盤還是鍵盤,那是下面的實 現(xiàn)不同了,通過這種構架,能保持軟件的彈性與可維護性。 依賴抽象是我們實現(xiàn)代碼擴展和運行期內(nèi)綁定(多態(tài))的基礎 因為一旦類的使用者依賴某個具體的類,那么對該依賴的擴展就無從談起;而依賴某個抽象類,則只 要實現(xiàn)了該抽象類的子類,都可以被類的使用者使用,從而實現(xiàn)了系統(tǒng)的擴展。 (4)示例(摘錄網(wǎng)上資料) 這里舉個比較好笑的例子:一個即將做領導的兒子問曾經(jīng)做領導的父親怎么才能平步青云,父親說你 不能說假話,因為老百姓會
8、不答應,也不能說實話,因為領導會對你有意見,兒子思索良久問:那我該說 什么?父親意味深長的說:空話 笑話不但好笑,還能反映一定的道理,為啥空話這么有用,因為他是抽象的,而抽象不涉及到一些具 體的數(shù)據(jù)或者事務,因此他是穩(wěn)定的,是不容易變化的,同時基本上也是正確的。 4、依據(jù)“依賴倒置原則”進行編程開發(fā) (1)體現(xiàn)倒置原則的 UML類圖 以前傳統(tǒng)的過程設計中是從上到下的一條依賴線 類的使用者服務的請求者) 接口的實現(xiàn)類(服務提供者) 現(xiàn)在是平的一條到接口,然后是一條從下往上的的關聯(lián)線。 (2)其主要的優(yōu)點 由于在依賴倒置中,通過抽象接口達到隔離了“服務的提供者”和“服務的請求者”,使它們之 間沒有
9、直接的耦合關系,兩者可以獨立地擴展或重用。 依賴倒置原則是許多面向對象技術的優(yōu)點的根本。合理地應用它對于建立可復用的框架是必要 的。對于構建富有變化彈力的代碼也是相當重要的。而且,由于抽象和具體相互完全分離,代碼 的維護就容易很多了。 依賴倒置原則一般應用于類與類之間的代碼級的依賴關系。 (3)應用依賴倒置原則的代碼示例 任何實例對象變量都不應該持有一個指向具體類的引用,而應該為接口類型的對象聲明 class SomeClass private Some In terface obj=n ull; 任何類都不應該從具體類派生,而應該實現(xiàn)某個接口-面向接口編程,而不要面向實現(xiàn)編程 class S
10、omeClassimpleme nts SomeI nterface / exte nds SuperClass 5、依賴倒置原則示例 (1)持久層中的各個組件常規(guī)的設計和實現(xiàn)方案 在很多Web應用系統(tǒng)中,都需要對后臺的數(shù)據(jù)庫系統(tǒng)進行訪問以實現(xiàn)數(shù)據(jù)存儲的目的。而一個常見的 解決手段是使用分層的設計思想和方法,將Web應用系統(tǒng)中的持久層中的各個組件分為數(shù)據(jù)訪問操作組件 (DAQ Data Access Object )和數(shù)據(jù)連接組件,下面的圖中所示為這種常規(guī)的設計和實現(xiàn)方案的類圖。 (2)常規(guī)設計和實現(xiàn)方案中所反映出的問題 從上面的圖中的所示的 數(shù)據(jù)訪問操作組件 和數(shù)據(jù)連接組件 之間的關系來看,
11、兩者產(chǎn)生了緊密的藕合關 系。一旦數(shù)據(jù)連接組件有了任何變化,數(shù)據(jù)訪問操作組件都有可能會受其影響而需要被改動。 當然,如果只是針對這兩個類本身而言的話,這種依賴關系根本算不上什么問題。然而,在一個實際 的應用系統(tǒng)中,數(shù)據(jù)訪問操作組件和數(shù)據(jù)連接組件都會由不只一個類而構成的,并都有一定的技術實現(xiàn)上 的復雜度,這時它們兩者之間的這種依賴關系就會增加系統(tǒng)的復雜性;而且隨著應用系統(tǒng)中的各個程序模 塊越來越多、功能實現(xiàn)也越來越復雜時,這種由于兩者之間的緊密藕合所帶來的系統(tǒng)的復雜度會越來越高。 因此,如果不限制它們之間的緊密藕合聯(lián)系,那模塊間的依賴、程序的復雜度和開發(fā)維護的難度都會成指 數(shù)上升。 (3)對設計進
12、行優(yōu)化在兩者之間添加一個抽象的接口 在兩者之間添加一個數(shù)據(jù)連接組件的接口,并在其中包含數(shù)據(jù)訪問操作組件中所需要的各種數(shù)據(jù)連接 的服務方法的定義,而某個具體的數(shù)據(jù)連接組件則實現(xiàn)這個接口。此時數(shù)據(jù)訪問操作組件則只需要調(diào)用數(shù) 據(jù)連接組件接口中的服務來實現(xiàn)數(shù)據(jù)庫的各種連接功能,兩者都只依賴于數(shù)據(jù)連接組件的接口。請見下面 的圖中所示的優(yōu)化設計結果的類圖。 這樣,數(shù)據(jù)訪問操作組件到數(shù)據(jù)連接組件的依賴關系被數(shù)據(jù)連接組件的接口所隔離開。因為在接口中 只包含了所需要的各種連接的服務功能的定義,而不包括任何連接的服務功能的具體實現(xiàn),所以數(shù)據(jù)連接 組件的接口的內(nèi)容在具體設計時也會很簡單。在數(shù)據(jù)連接組件接口不變的情況
13、下,數(shù)據(jù)訪問操作組件和某 個具體的數(shù)據(jù)連接組件這兩個模塊都可以自由地進行修改而不影響到對方(比如添加另一個數(shù)據(jù)連接組 件),依賴關系也變得簡單和可管理。 (4)進一步改進本設計和實現(xiàn)方案一一核心邏輯不依賴于具體的實現(xiàn)細節(jié) 如果從系統(tǒng)架構的角度來看上面的圖中所示的設計和實現(xiàn)方案還存在一定的問題,因為數(shù)據(jù)訪問操作 組件所提供的功能是整個應用系統(tǒng)的數(shù)據(jù)訪問的核心部分,而數(shù)據(jù)連接組件中的各個功能方法則可以看成 是具體實現(xiàn)的的細節(jié)。因此,從這個角度來看圖中優(yōu)化設計后的結果時,該設計是“核心邏輯依賴于具體 的實現(xiàn)細節(jié)”。當然,也就沒有遵守依賴倒置原則中的“抽象不能依賴于具體,具體依賴于抽象”的要求。 因為
14、,當細節(jié)變化(數(shù)據(jù)連接中的數(shù)據(jù)源或者連接方式發(fā)生變化)時,數(shù)據(jù)訪問操作組件中的核心邏 輯(數(shù)據(jù)訪問的實現(xiàn)邏輯)也會受到一定的影響。因為當應用系統(tǒng)中的數(shù)據(jù)存儲從某一種形式的數(shù)據(jù)庫系 統(tǒng)改變另一種形式的數(shù)據(jù)庫系統(tǒng)(比如從微軟的MS SQLServer2000改變?yōu)镺raclelOG數(shù)據(jù)庫系統(tǒng))時, 此時也將必然會影響到數(shù)據(jù)訪問操作組件中有關的的具體實現(xiàn)方法(因為對這兩種不同的數(shù)據(jù)庫系統(tǒng)在具 體進行數(shù)據(jù)訪問操作實現(xiàn)時的SQL語句或者涉及對存儲過程的調(diào)用時,是不一樣的!)。 為了能夠達到當系統(tǒng)中的數(shù)據(jù)庫類型發(fā)生變化時,不至于影響到對數(shù)據(jù)庫訪問組件的使用者(業(yè)務層 組件)的代碼,有必要對系統(tǒng)設計進一步完
15、善!下面的圖所示為這樣的應用場景下的各個類的設計要求的 圖示。 (5) 利用數(shù)據(jù)庫訪問操作的抽象接口進行隔離 因此,有必要對上面的圖中所體現(xiàn)出的設計結果進一步地改進和完善。主要的思路是將由于數(shù)據(jù)庫連 接方式的不同而造成的數(shù)據(jù)庫訪問操作的不同隔離開,在數(shù)據(jù)庫訪問操作這一層次同樣也設計出一個數(shù)據(jù) 庫訪問操作的抽象接口,并為該數(shù)據(jù)庫訪問操作的抽象接口提供不同的具體數(shù)據(jù)庫訪問操作的實現(xiàn)類。 這樣的設計能夠避免改動對數(shù)據(jù)庫訪問操作的使用類(一般為上層的業(yè)務層組件類)的代碼,下面的 圖為進一步完善后的設計結果的類圖。 控制反轉(loc-lnversion of Control) 1消解框架和我們的應用系統(tǒng)
16、類之間的依賴關系 前面依賴倒置原則描述的是類與類之間的代碼級的依賴關系。如果我們開發(fā)的系統(tǒng)是基于某種框架系 統(tǒng)來開發(fā)的,此時我們的類對目標框架的依賴關系就會更強烈一點。那么,該如何消解框架和我們的應用 系統(tǒng)類之間的依賴關系呢?利用控制反轉。 2、控制反轉 (1)什么是控制反轉 “好萊塢原則(不要調(diào)用我們,讓我們調(diào)用你)”。 (2)面向框架和面向系統(tǒng)類庫開發(fā)的不同點 框架和類庫最重要的區(qū)別是:框架是一個半成品的應用程序,而類庫只包含一系列可被應用 程序調(diào)用的類。 類庫給用戶提供了一系列可復用的類,這些類的設計都符合面向對象原則和模式。用戶使用時, 可以創(chuàng)建這些類的實例,或從這些類中繼承出新的派生
17、類,然后調(diào)用類中相應的功能。在這一過 程中,類庫總是被動地響應用戶的調(diào)用請求。 框架則會為某一特定目的實現(xiàn)一個基本的、可執(zhí)行的架構??蚣苤幸呀?jīng)包含了應用程序從啟動到 運行的主要流程,流程中那些無法預先確定的步驟留給用戶來實現(xiàn)。程序運行時,框架系統(tǒng)自動 調(diào)用用戶實現(xiàn)的功能組件。這時,框架系統(tǒng)的行為是主動的。 (3)應用系統(tǒng)和框架系統(tǒng)之間的依賴關系有以下特點 應用系統(tǒng)和框架系統(tǒng)之間實際上是雙向調(diào)用,雙向依賴的關系。 通過依賴倒置原則可以減弱應用系統(tǒng)到框架系統(tǒng)之間的依賴關系。 而利用“控制反轉”及具體的模板方法模式可以消解框架到應用系統(tǒng)之間的依賴關系,這也是所 有框架系統(tǒng)的基礎。 框架系統(tǒng)通過“控制
18、反轉”,最后能夠達到可以獨立地被重用。 (4)“控制反轉”的體現(xiàn) 傳統(tǒng)的面向類庫的做法,我們在自己的程序中調(diào)用一個個類庫去完成一個個功能,類庫是我們的執(zhí)行 體,但是邏輯算法等是自己實現(xiàn)的,這就是自己的控制。 但由于了框架后則不一樣,邏輯算法都是它來實現(xiàn),我們只要提供它幾個需要的接口或者執(zhí)行體就可。 這就是反轉,控制在框架這邊了-由框架來對我們的代碼進行調(diào)用。 其目的主要是簡化工作量,對于一些常見的業(yè)務場景不需要自己去重復實現(xiàn)。 3、應用框架是如何實現(xiàn)控制反轉 (1)利用模板方法模式 為上層的應用系統(tǒng)提供“模板方法模式”,因為在面向對象領域,“回調(diào)函數(shù)”(一般是面向系統(tǒng)類庫 開發(fā)時采用的手段)的
19、替代物就是“模板方法模式”(一般是面向應用框架開發(fā)時采用的手段)。 評昨蓋的鉤子加,實眼 (2)什么是模板方法模式 “模板方法模式”,也就是“好萊塢原則(不要調(diào)用我們,讓我們調(diào)用你) 統(tǒng)的基礎,任何框架系統(tǒng)都離不開模板方法模式 如Struts框架中的插件技術 public final class UserDatabasePlugI n public void destroy() public (3)Spring 【例11-34】 ”。模板方法模式是框架系 impleme nts Plugin void init(ActionServlet servlet,ModuleCo nfig con f
20、ig) throws ServletExceptio n 框架中的TransactionTemplate模板類的代碼 TransactionTemplate模板類的部分代碼示例 package org.springframework.transaction.support; / import 語句,在此加以省略 publicclassTransactionTemplate DefaultTransactionDefinition implements InitializingBean extends public Object execute(TransactionCallback Trans
21、actionException if (this.transactionManager instanceof action) throws CHINA-PUB.COM 円見詆上匕S A - CallbackPreferringPlatformTransactionManager) return (CallbackPreferringPlatformTransactionManager) this.transactionManager). execute(this, action); else TransactionStatus status =this.transactionManager.g
22、etTransaction(this); Object result = null; try / 對用戶的實現(xiàn)類中的 doInTransaction 方法進行回調(diào) result = action.doInTransaction(status); catch (RuntimeException ex) / 用戶的回調(diào)方法執(zhí)行失敗時將自動地進行事務回滾 rollbackOnException(status, ex); throw ex; catch (Error err) / 用戶的回調(diào)方法執(zhí)行失敗時將自動地進行事務回滾 rollbackOnException(status, err); thro
23、w err; / 用戶的回調(diào)方法執(zhí)行成功將自動地進行事務提交 this.transactionMmit(status); return result; / 其它的方法定義,在此加以省略 在下面的【例 11-35 】中所示的是 TransactionCallback 接口的代碼定義示例,該接口只有一個 doInTransaction 方法的聲明。該方法也就是前面的 TransactionTemplate 模板類中的“回調(diào)”方法(或 者是“鉤子”方法) 。 【例 11-35 】 TransactionCallback 接口的定義的代碼示例 package org.springframework.t
24、ransaction.support; import org.springframework.transaction.TransactionStatus; public interface TransactionCallback Object doInTransaction(TransactionStatus status); 4、“控制反轉”和“依賴倒置”的不同點 雖然 “依賴倒置” 和“控制反轉” 在設計層面上都是消解模塊耦合的有效方法, 也都是試圖令具體的、 易變的模塊依賴于抽象的、穩(wěn)定的模塊的基本原則,但二者在使用語境和關注點上存在差異。 ( 1)“倒置”的目標不同 “依賴倒置”強調(diào)的
25、是對于傳統(tǒng)的、源于面向過程設計思想的層次概念的“倒置” ,而“控制反轉” 強調(diào)的是對程序流程控制權的反轉; ( 2)應用的范圍不同 “依賴倒置”的使用范圍更為寬泛,既可用于對程序流程的描述(如流程的主從和層次關系) ,也可 用于描述其他擁有概念層次的設計模型(如服務組件與客戶組件、核心模塊與外圍應用等)。 而“控制反轉”則僅適用于描述流程控制權的場合(如算法流程或業(yè)務流程的控制權)。 我們也可以把“控制反轉”看作是“依賴倒置”的一個特例。例如,用模板方法模式實現(xiàn)的“控制反 轉”機制其實就是在框架系統(tǒng)和應用系統(tǒng)之間抽象出了一個描述所有算法步驟原型的接口類,框架系統(tǒng)依 賴于該接口類定義并實現(xiàn)程序流程,而應用系統(tǒng)依賴于該接口類提供具體算法步驟的實現(xiàn),應用系統(tǒng)對框 架系統(tǒng)的依
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度汽車租賃市場拓展及品牌合作合同3篇
- 2025年度個人挖掘機租賃合同-設備升級版4篇
- 二零二五年度出租車座套廣告合作知識產(chǎn)權保護合同4篇
- 二零二五年度水產(chǎn)養(yǎng)殖害蟲防治與漁業(yè)生產(chǎn)合同3篇
- 數(shù)字化營銷策略-第1篇-深度研究
- 二零二五年度農(nóng)家樂特色廚師雇傭協(xié)議書3篇
- 二零二五年度瓷磚美縫施工安全責任合同書4篇
- 地球流體動力學-第1篇-深度研究
- 工業(yè)互聯(lián)網(wǎng)權限模型構建-深度研究
- 2025年度農(nóng)家樂房屋租賃合同及文化傳承合作協(xié)議4篇
- 運動技能學習與控制課件第十一章運動技能的練習
- 蟲洞書簡全套8本
- 射頻在疼痛治療中的應用
- 四年級數(shù)學豎式計算100道文檔
- “新零售”模式下生鮮電商的營銷策略研究-以盒馬鮮生為例
- 項痹病辨證施護
- 職業(yè)安全健康工作總結(2篇)
- 懷化市數(shù)字經(jīng)濟產(chǎn)業(yè)發(fā)展概況及未來投資可行性研究報告
- 07FD02 防空地下室電氣設備安裝
- 教師高中化學大單元教學培訓心得體會
- 彈簧分離問題經(jīng)典題目
評論
0/150
提交評論