在開始新項目時,多數人計劃在將代碼投入生產發行之前審核它們;但是,當提交日程超越了其他因素時,審核常常成為第一個被拋棄的實踐。如果能夠自動執行其中一些審核,那么情況又會怎樣呢?在新系列 “讓開發自動化” 的第一篇文章中,開發自動化專家 Paul Duvall 首先將研究如何自動化檢查器(例如 CheckStyle、JavaNCSS 和 CPD)、如何改進開發過程,以及應該什么時候使用它們。
代碼檢查可以采用不同的形式。有些企業使用正式的同級評審(peer review),在該評審過程中,開發人員要為代碼提供同級評價,并提供改進意見;其他一些企業使用結對編程;還有一些人則考慮使用高級設計決策和推薦的代碼改進。有些團隊會在將代碼提交到版本控制存儲庫之前,讓其他開發人員用 “桌面檢查” 的形式審查他們的代碼。
不論企業采用哪種方式進行代碼檢查,有一件事是肯定的:它們幾乎都是手工過程。正如我多年所觀察到的,手工過程很容易出錯,如果工作緊張,就會忘記自己正在做什么。但是,軟件檢查不必總是手工完成;實際上,有一大堆開源工具和商業工具(我稱之為軟件檢查器),可以用它們很方便地對代碼進行靜態分析(這些工具也稱為靜態分析工具)。
使用軟件檢查器,代碼檢查可以通過 Ant 或 Maven 這樣的構建工具來自動完成。通過使用這種自動化,一些低級的源代碼細節(如編碼標準、復雜性和重復程度等)的處理成為了機器的職責。這種職責轉移通過將重點轉向更高級的開發方面(比如設計和長期維護問題)提高了人們手工檢查的效率。
![]() |
|
軟件檢查器有很多,范圍從復雜的商業工具到簡單的開源替代工具。但是,我發現其中三個特別有用,它們是 CheckStyle、CPD 和 JavaNCSS (請參閱 參考資料):
![]() |
|
我參與了幾家公司的委員會,花了很多時間來定義編碼標準。有一次,我們定義了幾乎沒人 遵守的 25 頁的編碼標準文檔。結果,我們的代碼審查非常痛苦,因為團隊要花時間來挑錯,看看開發人員是否使用了兩個空格規則(與四個空格規則相對),以及是否將參數聲明為 final
。如果把這些低級檢查工作交給軟件檢查器,我們會節省許多寶貴的時間。
使用自動的源代碼檢查工具(如 CheckStyle)可以提供執行可配置規則集的簡單途徑,規則集可以根據項目的編碼標準而定。此外,可以通過 CheckStyle 插件在 IDE 中運行 CheckStyle,CheckStyle 通過它的 Ant 任務或 Maven 插件直接集成到構建腳本中。CheckStyle 發現的所有規則偏離都會以報告的形式顯示,清楚地指出哪一個文件違規。除此之外,還可以將 Ant 和 Maven 配置成與 CheckStyle 相呼應,這樣,在違反規則時,構建工作就會失敗。
例如,清單 1 演示了 Ant 構建腳本的一個代碼段,它運行 CheckStyle 生成 HTML 報告。請注意 failOnViolation
屬性,在這里它被設為 false
。如果將該屬性設為 true
,則在發現任何 源代碼違規時,構建都會失敗。
<taskdef resource="checkstyletask.properties" classpath="${checkstyle.jar}"/><checkstyle config="${basedir}/cs-rules.xml" failOnViolation="false"> <formatter toFile="${checkstyle.data.file}" type="xml" /> <fileset casesensitive="yes" dir="${src.dir}" includes="**/*.java" /></checkstyle><xslt taskname="checkstyle" in="${checkstyle.data.file}" out="${checkstyle.report.file}" style="${checkstyle.xsl.file}" /> |
在清單 1 中,config
被設置成 cs-rules.xml
,這表示將根據源代碼目錄(在 fileset dir
屬性中)以遞歸的方式運行規則文件。xslt
任務接受根據 formatter toFile
屬性生成的文件。該任務使用 XSL 文件 checkstyle.xsl 將清單 1 生成的 XML 轉換成一個可讀的 HTML 文件,XSL 文件 checkstyle.xsl 包含在 CheckStyle 安裝文件中。
清單 2 是 CheckStyle 規則文件的示例片段。CheckStyle 可以在代碼基上運行 120 多個規則。
<module name="Checker"> <module name="TreeWalker"> <property name="cacheFile" value="target/checkstyle.cache"/> <property name="tabWidth" value="4"/> <module name="ImportOrder"> <property name="ordered" value="true"/> <property name="separated" value="true"/> </module> <module name="LineLength"> <property name="max" value="120"/> </module> <module name="FileLength"> <property name="max" value="400"/> </module> <module name="UnusedImports"/> </module></module> |
每個 CheckStyle 規則都是一個模塊。例如,LineLength
模塊建立的規則是:所有行中的字符都不得超過 120 個字符,否則 CheckStyle 就生成錯誤。