內容耦合
內容耦合
內容耦合是指如果一個模塊與另一個模塊的內部屬性有關,不經調用直接使用另一個模塊的程序代碼或內部數據,那麼這兩個模塊之間就存在內容耦合。這種耦合表明一個模塊與另一個模塊的內部數據或程序代碼有關,當一個模塊的程序代碼被修改或內部數據出錯,必然引起另一個模塊出錯。而對后一模塊的出錯是很難查出原因的,這樣給模塊的修改、維護帶來極大困難。內容耦合的耦合度最大,為“病態耦合”,在設計時,應避免這種耦合。
當一個模塊直接修改或操作另一個模塊的數據,或者直接轉入另一個模塊時,就發生了內容耦合。此時,被修改的模塊完全依賴於修改它的模塊。如果發生下列情形,兩個模塊之間就發生了內容耦合
(1) 一個模塊直接訪問另一個模塊的內部數據;
(2) 一個模塊不通過正常入口轉到另一模塊內部;
(3) 兩個模塊有一部分程序代碼重疊(只可能出現在彙編語言中);
(4) 一個模塊有多個入口。
以下是內容耦合的例子:
例子1:模塊p修改模塊q的一個語句。這個練習不僅限於彙編語言編程,現在,COBOL中已寬容地去掉了alter動詞,該動詞表示:它修改了另一個語句。
例子2 :根據模塊q內部用數字錶示的轉移,模塊p引用模塊q的局部數據。
例子3:模塊p分支轉移到模塊q的一個局部標號。
假設模塊p和模塊q之間內容耦合,許多危險之一是幾乎對q的任何修改,甚至用一個新的編譯器或彙編器重新編譯q,也要求對p進行修改。進一步說,在一個新產品中,如果不重用模塊q,則不可能重用模塊p。兩個模塊內容耦合時,它們不可避免地相互連接在一起。
在為面向對象系統進行構件級設計時,內聚性意味著構件或者類只封裝那些相互關聯密切,以及與構件或類自身有密切關係的屬性和操作。Lethbridge和Laganiere定義了許多類型的內聚性(按內聚性級別排序。一般來說,內聚性級別越高,構件的實現、測試和維護就越容易)。
1、功能內聚。主要通過操作來體現,當一個模塊只完成某一組特定操作並返回結果時,就稱此模塊是功能內聚的。
2、分層內聚。由包、構件和類來體現。高層能夠訪問低層的服務,但低層不能訪問高層的服務。例如,如果警報響起,SafeHome的安全功能需要打出一個電話。可以定義如下圖所示的一組分層包,帶陰影的包中包含基礎構件。訪問都是從Control panel包向下進行的。
3、通信內聚。訪問相同數據的所有操作被定義在一個類中。一般來說,這些類只著眼於數據的查詢、訪問和存儲。
那些體現出功能、層和通信等內聚性的類和構件,相對來說易於實現、測試和維護。設計者應該儘可能獲得這些級別的內聚性。然而,需要強調的是,實際的設計和實現問題有時會迫使設計者選擇低級別的內聚性。
通信和協作是面向對象系統中的基本要素,然而這個重要(必要)特徵存在一個缺陷。隨著通信和協作數量的增長(也就是說,隨著類之間的聯繫程度越來越強),系統的複雜性也隨之增長了。同時,隨著系統複雜度的增長,軟體實現、測試和維護的困難也隨之增大。
耦合是類之間彼此聯繫程度的一種定性度量。隨著類(構件)相互依賴越來越多,類之間的耦合程度也會增加。在構件級設計中,一個重要的目標就是儘可能保持低耦合。
有多種方法表示類之的耦合,列舉如下:
1、內容耦合。當一個構件“暗中修改其他構件的內部數據”時,就會發生這種類型的耦合。這違反了基本設計概念當中的信息隱蔽原則。
2、共用耦合。當大量的構件都要使用同一個全局變數時發生這種耦合。儘管有時候這樣做是必要的(例如,設立一個在整個應用系統中都可以使用的默認值),但是當這種耦合發生變更時,會導致不可控制的錯誤蔓延和不可預見的副作用。
3、控制耦合。當操作A調用操作B,並且向B傳遞控制標記時,就會發生這種耦合。接著,控制標記將會指引B中的邏輯流程。這種耦合形式的主要問題在於B中的一個不相關變更,往往能夠導致A所傳遞控制標記的意義也必須發生變更。如果忽略這個問題,就會引起錯誤。