大多數設計良好的軟件架構都趨向于支持系統的可擴展性、可維護性和可靠性。遺憾的是,對質量問題的疏忽極可能使軟件架構師的努力白費。在追求代碼質量 系列的這一期文章中,質量專家 Andrew Glover 解釋如何持續地監視并糾正會影響軟件架構的長期生存能力的代碼質量方面。
上一期文章中,我展示了如何使用代碼度量來評估代碼質量。盡管在那一期介紹的圈復雜度針對低級細節,如方法中執行路徑的數量,但其他類型的度量針對的是代碼的更高級方面。在本期文章中,我將展示如何使用各種耦合度量 來分析和支持軟件架構。
我將從兩個比較有趣的耦合度量開始,即傳入耦合 和傳出耦合。這些基于整數的度量表示幾個相關對象(即相互協調以產生行為的對象)。任一度量中高數值表示架構的維護問題:高傳入耦合表示對象具有太多職責,而高傳出耦合表示對象不夠獨立。在本期文章中,我將介紹每個這樣的問題及其解決的方法。
具有太多職責并非什么壞事。例如,組件(或包)通常試圖用于整個架構中,這就會給它們帶來高傳入耦合值。核心框架(如 Strut)、登錄包(如 log4j)之類的實用工具以及異常層次結構通常具有高傳入耦合。
在圖 1 中,可以看到一個包 com.acme.ascp.exception
具有一個值為 4 的傳入耦合。這并不奇怪,因為 web
、dao
、util
和 frmwrk
包都希望利用一個公共的異?蚣。
圖 1. 傳入耦合的符號

如圖 1 所示,exception
包具有一個值為 4 的傳入耦合(或者叫做 Ca),這并非是件壞事。異常層次結構很少會出現很大的改變。監視 exception
包的傳入耦合是個好主意,然而,由于徹底改變了這個包中的行為或契約,所以將引起它的四個依賴包全都出現連鎖反應。
![]() ![]() |
![]()
|
通過進一步檢查 exception
包并注意抽象到具體類的比率,可以派生出另一個度量:抽象性。在本例中,exception
包具有零抽象性,因為它的所有類都是具體的。這與我前面的觀察是一致的:exception
包中的高度具體性表示對 exception
作出的任何更改將影響所有相關包,即 com.acme.ascp.frmwrk
、com.acme.ascp.util
、com.acme.ascp.dao
和 com.acme.ascp.web
。
通過理解傳入耦合表示組件的職責,并持續監視這個度量,可以防止軟件架構出現熵(entropy),即使在大多數設計良好的系統中也很容易出現熵。
很多架構設計在利用第三方包時都考慮到了靈活性。獲得靈活性最好是通過使用接口來防止架構在第三方包中發生更改。例如,系統設計師可以創建一個內部接口包 來利用第三方記帳代碼,但是只對這些使用記帳代碼的包公開接口。順便說一下,這與 JDBC 的工作原理類似。
圖 2. 通過設計獲得靈活性

如圖 2 所示,acme.ascp 應用程序通過 com.acme.ascp.billing
包與第三方記帳包相耦合。這創建了一定級別的靈活性:如果有了另一個第三方記帳包更加有利用價值,那么應該只有一個包會受到變更的影響。此外,com.acme.ascp.billing
的抽象性值是 0.8,這表明它可以通過接口和抽象類來防止被修改。
如果要轉換到第三方實現,只需要對 com.acme.ascp.billing
包進行重構。更好的方法是:通過在設計中考慮靈活性以及了解變更的隱含意義,可以通過開發人員測試來防止修改所造成的任何損害。
在對內部記帳包作出變更前,您可以分析代碼覆蓋率報告,以確定是否有任何測試真正 測試了這個包。找到一些級別的覆蓋率后,您可以更仔細地檢查這些測試案例來驗證它們是否足夠了。如果未找到覆蓋率,您將會知道,關閉并插入新庫的努力將更具風險性并可能花費更長的時間。
使用代碼度量收集所有這些似乎正確的信息非常容易。另一方面,如果您根本不了解與測試覆蓋率相關的包耦合的知識,那么為替換第三方庫確定的時間最多就是個猜測!
文章來源于領測軟件測試網 http://www.kjueaiud.com/