我們在開發(fā)Java項目時經(jīng)常會遇到關(guān)于包混亂的問題,特別是在架構(gòu)更改后,這樣的問題尤為突出,JDepend工具可以幫助你在開發(fā)過程中隨時跟蹤每個包的依賴性(引用/被引用),從而設(shè)計高維護性的架構(gòu),不論是在打包發(fā)布還是版本升級都會更加輕松。
本文引自
http://starrynight.blogdriver.com/starrynight/606590.html,并增加了些自己的見解,感謝
starrynightJDepend是一個開源的工具,并配有Eclipse插件,在實際應(yīng)用中,JDepend遍歷所有的Java代碼目錄,自動生成每個Package的依賴性度量。對于可擴展性、可重用性和可管理性,JDepend可自動度量一個設(shè)計在以上三個方面的質(zhì)量。
Eclipse插件的下載地址為:http://andrei.gmxhome.de/eclipse/
運行方法是右鍵選擇需要分析的包,選擇 Run JDepend Analysis

于是會出現(xiàn)如下分析結(jié)果

JDepend為每個Package自動生成的依賴性度量指標,包括:
被分析package的具體和抽象類(和接口)的數(shù)量,用于衡量package的可擴展性。
如果一個類中實現(xiàn)了其他類,如實現(xiàn)了監(jiān)聽類,則監(jiān)聽類的數(shù)目也記錄在此。
例如:
??? private IPartListener partListener = new IPartListener() {
??????? public void partActivated(IWorkbenchPart part) {
??????????? if (part instanceof IEditorPart)
??????????????? editorActivated((IEditorPart) part);
??????? }
??????? public void partBroughtToTop(IWorkbenchPart part) {
??????? }
??????? public void partClosed(IWorkbenchPart part) {
??????? }
??????? public void partDeactivated(IWorkbenchPart part) {
??????? }
??????? public void partOpened(IWorkbenchPart part) {
??????? }
??? };
依賴于被分析package的其他package的數(shù)量,用于衡量pacakge的職責(zé)。
即有多少包調(diào)用了它。
被分析package的類所依賴的其他package的數(shù)量,用于衡量package的獨立性。
即它調(diào)用了多少其他包。
被分析package中的抽象類和接口與所在package所有類數(shù)量的比例,取值范圍為0-1。
I=Ce/(Ce+Ca),用于衡量package的不穩(wěn)定性,取值范圍為0-1。I=0表示最穩(wěn)定,I=1表示最不穩(wěn)定。
即如果這個類不調(diào)用任何其他包,則它是最穩(wěn)定的。
被分析package和理想曲線A+I=1的垂直距離,用于衡量package在穩(wěn)定性和抽象性之間的平衡。理想的package要么完全是抽象類和穩(wěn)定(x=0,y=1),要么完全是具體類和不穩(wěn)定(x=1,y=0)。
取值范圍為0-1,D=0表示完全符合理想標準,D=1表示package最大程度地偏離了理想標準。
即你的包要么全是接口,不調(diào)用任何其他包(完全是抽象類和穩(wěn)定),要么是具體類,不被任何其他包調(diào)用。
為什么使用JDepend
- 評價設(shè)計質(zhì)量
- 翻轉(zhuǎn)依賴性
- 支持并行開發(fā)和極限編程
- 獨立的發(fā)布模塊
- 識別package的循環(huán)依賴
安裝JDepend
安裝JDepend很簡單,只需下載jdepend-
.zip并解壓縮,然后把jdepend-.jar加入系統(tǒng)類路徑。
和Ant集成
<property name="jdepend.log.dir" value="${tomcat.home}/webapps/cruisecontrol/jdepend" />
<taskdef name="jdepend" classname="org.apache.tools.ant.taskdefs.optional.jdepend.JDependTask">
?????? <classpath refid="classpath.lib" />
</taskdef>
<target name="jdepend" depends="compile">
??? <jdepend format="xml" outputfile="${jdepend.log.dir}/jdepend-report.xml">
??????? <exclude name="java.*"/>
??????? <exclude name="javax.*"/>
??????? <exclude name="org.*"/>
??????? <exclude name="junit.*"/>
??????? <exclude name="net.*"/>
??????? <exclude name="mx4j.*"/>
??????? <exclude name="com.anmeng.*"/>
??????? <exclude name="testdomain.*"/>
??????? <exclude name="thinlet.*"/>
??????? <exclude name="**/*Test*"/>
??????? <classpath refid="classpath.lib" />
??????? <classespath location="${classes.main}" />
??? </jdepend>
??? <style basedir="${jdepend.log.dir}" destdir="${jdepend.log.dir}"
??????????? includes="jdepend-report.xml"
??????????? style="${jdepend.log.dir}/jdepend.xsl">
??????? <classpath refid="ant.lib" />
??? </style>
</target>
集成CruiseControl
在CruiseControl的buildresults.jsp文件中加入:
<cruisecontrol:xsl xslFile="/xsl/jdepend.xsl"/>