




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、依賴和耦合關系 1、依賴和耦合( Dependency and Coupling ) ( 1)什么是依賴 Rose 的幫助文檔上是這樣定義“依賴”關系的: “依賴描述了兩個模型元素之間的關系,如果被依賴 的模型元素發生變化就會影響到另一個模型元素。典型的,在類圖上,依賴關系表明客戶類的操作會調用 服務器類的操作。 ” ( 2)什么是耦合 Martin Fowler 在 Reducing Coupling 一文中這樣描述耦合: “如果改變程序的一個模塊要求另一個 模塊同時發生變化,就認為這兩個模塊發生了耦合。 ” Fowler 2001 從上面的定義可以看出:如果模塊 A 調用模塊 B 提供的方
2、法,或訪問模塊 B 中的某些數據成員(當 然,在面向對象開發中一般不提倡這樣做) ,我們就認為模塊 A 依賴于模塊 B ,模塊 A 和模塊 B 之間發生 了耦合。 耦合是依賴的同義詞,被定義為“兩個元素之間的一種關系,其中一個元素變化,導致另一個元素變 化”。抽象耦合被定義為“若類 A 維護一個指向抽象類 B 的引用,則稱類 A 抽象耦合于 B”。 2、依賴是不可避免的 ( 1)“分而治之”的問題處理方法 對于復雜的系統,我們常常采用它劃分成多個模塊,這樣將能夠有效地控制模塊的復雜度,使每個模 塊都易于理解和維護。 ( 2)“分而治之”的結果是產生依賴關系 一旦我們采用 “分而治之”的處理方法
3、后, 模塊之間就必須以某種方式交換信息,也就是必然要 發生某種耦合關系。 如果某個模塊和其它模塊沒有任何關聯(哪怕只是潛在的或隱含的依賴關系) ,我們就幾乎可以 斷定,該模塊不屬于此軟件系統,應該從系統中剔除。 如果所有模塊之間都沒有任何耦合關系,其結果必然是:整個軟件不過是多個互不相干的系統的 簡單堆積, 對每個系統而言, 所有功能還是要在一個模塊中實現, 這等于沒有做任何模塊的分解。 ( 3)依賴是不可避免的 因此,模塊之間必定會有這樣或那樣的依賴關系, 我們永遠也不要幻想消除所有的依賴(耦合關系) 。 我們在類的設計時,應該首先考慮的是該類應該盡可能依賴不經常變化的“目標” 比如,系統的
4、 API 庫或者框架中的組件 試圖令具體的、易變的模塊依賴于抽象的、穩定的模塊的基本原則。 在 Java 中,表示字符串的是具體內 String 。該類是穩定的,也就是說,它不太會改變。因此,直接依 賴于它不會造成損害。 既然變化不可避免,我們所能做的就是處理好依賴關系,將變化造成的影響的波及范圍盡量減小。 ( 4)我們所追求的是盡可能降低過強的耦合關系 “依賴”是和“變化”緊密聯系在一起的概念。由于依賴關系的存在,變化在某處發生時,影響會波 及開去,造成很多修改工作,這就是依賴的危害。 因為,過強的耦合關系(如一個模塊的變化會造成一個或多個其他模塊也同時發生變化的依賴關 系)會對軟件系統的質
5、量造成很大的危害。 特別是當需求發生變化時,代碼的維護成本將非常高。所以,我們必須想盡辦法來控制和消解不 必要的耦合,特別是那種會導致其它模塊發生不可控變化的依賴關系。 ( 5)如何達到 采用什么的策略或者方法 依賴倒置、控制反轉、依賴注入等原則。 3、依賴倒置( DIPDependency Inversion Principle ) ( 1)什么是依賴倒置 將依賴關系倒置為依賴接口 依賴倒置原則就是建立在抽象接口的基礎上的。 Robert Martin 這樣描述依賴倒置原則 Martin 1996 : 上層模塊不應該依賴于下層模塊,它們共同依賴于一個抽象。 抽象不能依賴于具體,具體依賴于抽象
6、-也就是“系統的核心邏輯”不依賴于“具體的實現細 節”。 依賴性倒置原則形式化了抽象耦合的概念,明確表述了應該“依賴于抽象類,不要依賴于具體類” (2)如何達到依賴倒置的效果 為了消解兩個模塊間的依賴關系,應該在兩個模塊之間定義一個抽象接口,上層模塊調用抽象接口定 義的方法,下層模塊實現該接口。 類的使用者服務的請求者) 針對接口編程遵守上述原則,從而在很大程度上阻止了變化波及范圍的擴大,有效地隔離了變化,有 助于增強系統的可重用性和可擴展性。 (3)為什么要依賴接口 因為抽象是相對穩定的或者是相對變化不頻繁的,而具體是易變的 因此,要使我們的設計具有很大的靈活性,就需要做到大家都依賴于抽象的
7、東西,而利用抽象隔離具 體類之間的關系,這樣使得“具體”的任何改動都可以在局部范圍內實現,而不影響其它的結構。 比如,一個10系統它必然就有 READ/WRITE這兩個抽象,至于具體是磁盤還是鍵盤,那是下面的實 現不同了,通過這種構架,能保持軟件的彈性與可維護性。 依賴抽象是我們實現代碼擴展和運行期內綁定(多態)的基礎 因為一旦類的使用者依賴某個具體的類,那么對該依賴的擴展就無從談起;而依賴某個抽象類,則只 要實現了該抽象類的子類,都可以被類的使用者使用,從而實現了系統的擴展。 (4)示例(摘錄網上資料) 這里舉個比較好笑的例子:一個即將做領導的兒子問曾經做領導的父親怎么才能平步青云,父親說你
8、 不能說假話,因為老百姓會不答應,也不能說實話,因為領導會對你有意見,兒子思索良久問:那我該說 什么?父親意味深長的說:空話 笑話不但好笑,還能反映一定的道理,為啥空話這么有用,因為他是抽象的,而抽象不涉及到一些具 體的數據或者事務,因此他是穩定的,是不容易變化的,同時基本上也是正確的。 4、依據“依賴倒置原則”進行編程開發 (1)體現倒置原則的 UML類圖 以前傳統的過程設計中是從上到下的一條依賴線 類的使用者(服務的請求者) 接口的實現類服務提供者) 現在是平的一條到接口,然后是一條從下往上的的關聯線。 類的使用者服務的請求者) 按口的弄現姜(膽務提供者) (2)其主要的優點 由于在依賴倒
9、置中,通過抽象接口達到隔離了“服務的提供者”和“服務的請求者”,使它們之 間沒有直接的耦合關系,兩者可以獨立地擴展或重用。 依賴倒置原則是許多面向對象技術的優點的根本。合理地應用它對于建立可復用的框架是必要 的。對于構建富有變化彈力的代碼也是相當重要的。而且,由于抽象和具體相互完全分離,代碼 的維護就容易很多了。 依賴倒置原則一般應用于類與類之間的代碼級的依賴關系。 (3)應用依賴倒置原則的代碼示例 任何實例對象變量都不應該持有一個指向具體類的引用,而應該為接口類型的對象聲明 class SomeClass private Some In terface obj=n ull; 任何類都不應該從
10、具體類派生,而應該實現某個接口-面向接口編程,而不要面向實現編程 class SomeClass impleme nts SomeI nterface / exte nds SuperClass 5、依賴倒置原則示例 (1)持久層中的各個組件常規的設計和實現方案 在很多Web應用系統中,都需要對后臺的數據庫系統進行訪問以實現數據存儲的目的。而一個常見的 解決手段是使用分層的設計思想和方法,將Web應用系統中的持久層中的各個組件分為數據訪問操作組件 (DAQ Data Access Object )和數據連接組件,下面的圖中所示為這種常規的設計和實現方案的類圖。 (2)常規設計和實現方案中所反映
11、出的問題 從上面的圖中的所示的 數據訪問操作組件 和數據連接組件 之間的關系來看,兩者產生了緊密的藕合關 系。一旦數據連接組件有了任何變化,數據訪問操作組件都有可能會受其影響而需要被改動。 當然,如果只是針對這兩個類本身而言的話,這種依賴關系根本算不上什么問題。然而,在一個實際 的應用系統中,數據訪問操作組件和數據連接組件都會由不只一個類而構成的,并都有一定的技術實現上 的復雜度,這時它們兩者之間的這種依賴關系就會增加系統的復雜性;而且隨著應用系統中的各個程序模 塊越來越多、功能實現也越來越復雜時,這種由于兩者之間的緊密藕合所帶來的系統的復雜度會越來越高。 因此,如果不限制它們之間的緊密藕合聯
12、系,那模塊間的依賴、程序的復雜度和開發維護的難度都會成指 數上升。 (3)對設計進行優化在兩者之間添加一個抽象的接口 在兩者之間添加一個數據連接組件的接口,并在其中包含數據訪問操作組件中所需要的各種數據連接 的服務方法的定義,而某個具體的數據連接組件則實現這個接口。此時數據訪問操作組件則只需要調用數 據連接組件接口中的服務來實現數據庫的各種連接功能,兩者都只依賴于數據連接組件的接口。請見下面 的圖中所示的優化設計結果的類圖。 這樣,數據訪問操作組件到數據連接組件的依賴關系被數據連接組件的接口所隔離開。因為在接口中 只包含了所需要的各種連接的服務功能的定義,而不包括任何連接的服務功能的具體實現,
13、所以數據連接 組件的接口的內容在具體設計時也會很簡單。在數據連接組件接口不變的情況下,數據訪問操作組件和某 個具體的數據連接組件這兩個模塊都可以自由地進行修改而不影響到對方(比如添加另一個數據連接組 件),依賴關系也變得簡單和可管理。 (4)進一步改進本設計和實現方案一一核心邏輯不依賴于具體的實現細節 如果從系統架構的角度來看上面的圖中所示的設計和實現方案還存在一定的問題,因為數據訪問操作 組件所提供的功能是整個應用系統的數據訪問的核心部分,而數據連接組件中的各個功能方法則可以看成 是具體實現的的細節。因此,從這個角度來看圖中優化設計后的結果時,該設計是“核心邏輯依賴于具體 的實現細節”。當然
14、,也就沒有遵守依賴倒置原則中的“抽象不能依賴于具體,具體依賴于抽象”的要求。 因為,當細節變化(數據連接中的數據源或者連接方式發生變化)時,數據訪問操作組件中的核心邏 輯(數據訪問的實現邏輯)也會受到一定的影響。因為當應用系統中的數據存儲從某一種形式的數據庫系 統改變另一種形式的數據庫系統(比如從微軟的MS SQLServer2000改變為OraclelOG數據庫系統)時, 此時也將必然會影響到數據訪問操作組件中有關的的具體實現方法(因為對這兩種不同的數據庫系統在具 體進行數據訪問操作實現時的SQL語句或者涉及對存儲過程的調用時,是不一樣的!)。 為了能夠達到當系統中的數據庫類型發生變化時,不
15、至于影響到對數據庫訪問組件的使用者(業務層 組件)的代碼,有必要對系統設計進一步完善!下面的圖所示為這樣的應用場景下的各個類的設計要求的 圖示。 (5) 利用數據庫訪問操作的抽象接口進行隔離 因此,有必要對上面的圖中所體現出的設計結果進一步地改進和完善。主要的思路是將由于數據庫連 接方式的不同而造成的數據庫訪問操作的不同隔離開,在數據庫訪問操作這一層次同樣也設計出一個數據 庫訪問操作的抽象接口,并為該數據庫訪問操作的抽象接口提供不同的具體數據庫訪問操作的實現類。 這樣的設計能夠避免改動對數據庫訪問操作的使用類(一般為上層的業務層組件類)的代碼,下面的 圖為進一步完善后的設計結果的類圖。 11
16、/ 10 控制反轉(loc-lnversion of Control ) 1消解框架和我們的應用系統類之間的依賴關系 前面依賴倒置原則描述的是類與類之間的代碼級的依賴關系。如果我們開發的系統是基于某種框架系 統來開發的,此時我們的類對目標框架的依賴關系就會更強烈一點。那么,該如何消解框架和我們的應用 系統類之間的依賴關系呢?利用控制反轉。 2、控制反轉 (1)什么是控制反轉 “好萊塢原則(不要調用我們,讓我們調用你)”。 (2)面向框架和面向系統類庫開發的不同點 框架和類庫最重要的區別是:框架是一個半成品的應用程序,而類庫只包含一系列可被應用 程序調用的類。 類庫給用戶提供了一系列可復用的類,
17、這些類的設計都符合面向對象原則和模式。用戶使用時, 可以創建這些類的實例,或從這些類中繼承出新的派生類,然后調用類中相應的功能。在這一過 程中,類庫總是被動地響應用戶的調用請求。 框架則會為某一特定目的實現一個基本的、可執行的架構。框架中已經包含了應用程序從啟動到 運行的主要流程,流程中那些無法預先確定的步驟留給用戶來實現。程序運行時,框架系統自動 調用用戶實現的功能組件。這時,框架系統的行為是主動的。 (3)應用系統和框架系統之間的依賴關系有以下特點 應用系統和框架系統之間實際上是雙向調用,雙向依賴的關系。 通過依賴倒置原則可以減弱應用系統到框架系統之間的依賴關系。 而利用“控制反轉”及具體
18、的模板方法模式可以消解框架到應用系統之間的依賴關系,這也是所 有框架系統的基礎。 框架系統通過“控制反轉”,最后能夠達到可以獨立地被重用。 (4)“控制反轉”的體現 傳統的面向類庫的做法,我們在自己的程序中調用一個個類庫去完成一個個功能,類庫是我們的執行 體,但是邏輯算法等是自己實現的,這就是自己的控制。 但由于了框架后則不一樣,邏輯算法都是它來實現,我們只要提供它幾個需要的接口或者執行體就可。 這就是反轉,控制在框架這邊了-由框架來對我們的代碼進行調用。 其目的主要是簡化工作量,對于一些常見的業務場景不需要自己去重復實現。 3、應用框架是如何實現控制反轉 (1)利用模板方法模式 為上層的應用
19、系統提供“模板方法模式”,因為在面向對象領域,“回調函數”(一般是面向系統類庫 開發時采用的手段)的替代物就是“模板方法模式”(一般是面向應用框架開發時采用的手段)。 (2)什么是模板方法模式 “模板方法模式”,也就是“好萊塢原則(不要調用我們,讓我們調用你) 統的基礎,任何框架系統都離不開模板方法模式 如Struts框架中的插件技術 public final class UserDatabasePlugI n public void destroy() public (3)Spring 【例11-34】 ”。模板方法模式是框架系 impleme nts Plugin void init(Ac
20、tionServlet servlet,ModuleCo nfig con fig) throws 框架中的TransactionTemplate模板類的代碼 TransactionTemplate模板類的部分代碼示例 package org.springframework.transaction.support; / import 語句,在此加以省略 publicclassTransactionTemplate DefaultTransactionDefinition implements InitializingBean public Object execute(TransactionC
21、allback TransactionException if (this.transactionManager instanceof action) ServletExceptio n extends throws CallbackPreferringPlatformTransactionManager) return (CallbackPreferringPlatformTransactionManager) this.transactionManager). execute(this, action); else TransactionStatus status =this.transa
22、ctionManager.getTransaction(this); Object result = null; try / 對用戶的實現類中的 doInTransaction 方法進行回調 result = action.doInTransaction(status); catch (RuntimeException ex) / 用戶的回調方法執行失敗時將自動地進行事務回滾 rollbackOnException(status, ex); throw ex; catch (Error err) / 用戶的回調方法執行失敗時將自動地進行事務回滾 rollbackOnException(stat
23、us, err); throw err; / 用戶的回調方法執行成功將自動地進行事務提交 this.transactionMmit(status); return result; / 其它的方法定義,在此加以省略 在下面的【例 11-35 】中所示的是 TransactionCallback 接口的代碼定義示例,該接口只有一個 doInTransaction 方法的聲明。該方法也就是前面的 TransactionTemplate 模板類中的“回調”方法(或 者是“鉤子”方法) 。 【例 11-35 】 TransactionCallback 接口的定義的代碼示例 package org.spr
24、ingframework.transaction.support; import org.springframework.transaction.TransactionStatus; public interface TransactionCallback Object doInTransaction(TransactionStatus status); 4、“控制反轉”和“依賴倒置”的不同點 雖然 “依賴倒置” 和“控制反轉” 在設計層面上都是消解模塊耦合的有效方法, 也都是試圖令具體的、 易變的模塊依賴于抽象的、穩定的模塊的基本原則,但二者在使用語境和關注點上存在差異。 ( 1)“倒置”的
25、目標不同 “依賴倒置”強調的是對于傳統的、源于面向過程設計思想的層次概念的“倒置” ,而“控制反轉” 強調的是對程序流程控制權的反轉; ( 2)應用的范圍不同 “依賴倒置”的使用范圍更為寬泛,既可用于對程序流程的描述(如流程的主從和層次關系) ,也可 用于描述其他擁有概念層次的設計模型(如服務組件與客戶組件、核心模塊與外圍應用等)。 而“控制反轉”則僅適用于描述流程控制權的場合(如算法流程或業務流程的控制權)。 我們也可以把“控制反轉”看作是“依賴倒置”的一個特例。例如,用模板方法模式實現的“控制反 轉”機制其實就是在框架系統和應用系統之間抽象出了一個描述所有算法步驟原型的接口類,框架系統依 賴于該接口類定義并實現程序流程,而應用系統依賴于該接口類提供
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 抵押車輛轉讓合同范本
- 2025企業貸款合同模板下載
- 村內環境衛生整治協議書
- 《2025合同終止證明書》
- T/NAHIEM 59-2022家用凈水壺
- 家具自主維修合同范本
- 單位職工住房入住協議書
- 中國數字貨幣合作協議書
- 外發加工保密合同范本
- 石家莊信息工程職業學院《成本管理會計》2023-2024學年第二學期期末試卷
- 干部履歷表填寫范本(中共中央組織部1999年)
- 勞動教育視角下高職院校學生工匠精神培育研究
- 2024年湖南省高中學業水平合格考物理試卷真題(含答案詳解)
- 2024詳解反電信詐騙及預防電信詐騙主題課件
- 2024年(學習強國)思想政治理論知識考試題庫與答案
- 《文物學概論》習題與答案
- 2024年中考地理二輪復習專題-地理實踐與跨學科主題學習(解析版)
- 最簡單封陽臺安全免責協議書
- SH/T 3533-2024 石油化工給水排水管道工程施工及驗收規范(正式版)
- 用友人力資源管理HR解決方案樣本
- 維保服務方案及維保體系
評論
0/150
提交評論