Code Review與CheckStyle

Code Review與CheckStyle
本文向大家介紹Code Review的主要內容,以及流行的檢查Code Conventions的工具。同時,對於目前應用最爲廣泛的CheckStyle的應用給出詳細的介紹,同時,也列舉了很多使用CheckStyle的最佳實踐。

1. Code Review & Code Conventions
質量是衡量一個軟件是否成功的關鍵要素。而對於商業軟件系統,尤其是企業應用軟件系統來說,除了軟件運行質量、文檔質量以外,代碼的質量也是非常重要的。軟件開發進行到編碼階段的時候,最大的風險就在於如何保證代碼的易讀性和一致性,從而使得軟件的維護的代價不會很高。

在軟件開發的過程中,以下幾種情形隨處可見:

1. 軟件維護時間長,而且維護人員的積極性不高:

做過軟件維護的開發人員,尤其是在接手不是自己開發產品的源碼的時候,即使有良好的文檔說明,仍然會對代碼中冗長、沒有註釋的段落“歎爲觀止”。理解尚且如此困難,何況要修改或者增加新的功能。因此,很多開發人員不願意進行軟件維護的工作。

2. 新的開發人員融入團隊的時間比較長:

除了沒有良好的培訓、文檔等有效的機制以外,每個人一套的編碼風格,也容易造成新成員對於已有代碼的理解不夠,甚至出現偏差。

編碼規範,作爲解決以上問題的方案已經得到了很長時間的應用。而在產品或者項目實際開發的過程中,僅有Code Conventions是不能解決Code的問題的。它往往和Code Review配合,作爲代碼質量保證的手段。
1.1. Code Review的層次與內容
Code Review就是審查代碼的質量。根據形式分爲兩種,一種是交叉代碼審查,就是自己的代碼由他人來檢查,就象檢查作業一樣;另一種是代碼會審,就是以會議的形式,大家共同審覈代碼的質量。

Code Review 的目的有[2]:

² 在項目早期就能夠發現代碼中的BUG;
² 幫助初級開發人員學習高級開發人員的經驗,達到知識共享;
² 避免開發人員犯一些很常見,很普通的錯誤;
² 保證項目組人員的良好溝通;
² 項目或產品的代碼更容易維護;

一般情況下,Code Review的內容與層次如下:

² 編碼風格與代碼規範一致性:檢查代碼是否符合編碼規範,確保所有人寫的代碼基本一致;
² 代碼滿足基本的功能要求:檢查代碼的邏輯實現,以及單元測試的編寫策略,確認實現功能性需求;
² 代碼滿足性能等非功能性需求:非功能性需求一般不便於測試,需要藉助一定的工具和Review人員的素質,針對編碼中對於性能影響的瓶頸給出解決方案;
² 去除冗餘,提高代碼可讀性:適當使用 Refactorying技術,去除代碼中的Bad Smell;如果有需要,可以Refactorying to Pattern。
1.2. Code Conventions的尷尬境地
從Code Review的層次分析中我們可以看到,Code Conventions是其基礎。而實際的情況是,在軟件開發中,兩者都淪爲“宣傳口號”,而非切實執行的實踐。

造成這種情形的原因有二:

1. Code Conventions是開發過程的“道德”而非“法律”:很多時候,由於沒有有效的工具或者輔助手段的支持,是否遵守編碼規範是依靠開發人員的“道德素養”-自覺遵守,而非實際考覈的指標;

2. Code Review的基石不牢:在第一種原因的影響下,Code Review執行的過程中,如果花費了大量的時間在代碼規範的檢查上,那麼對於更爲重要的程序執行邏輯、性能、易讀性等的評審投入的精力就有限的;而這種情況反過來也使得對於編碼規範的檢查,通常都是走過場。最後,還是每個人一套規範,只要最終交付的產品完成指定的功能就可以啦。
2. CheckStyle
面對以上描述的Code Conventions的尷尬境地,陸續有開發人員提出了自己的解決方案。目前,對於JAVA的代碼規範的檢查,已經有很多成熟的工具,例如CheckStyle、PMD以及Jalopy等[3]。其中,CheckStyle的應用非常廣泛,衆多開源項目都使用它作爲檢查代碼規範的工具,尤其是 Jakarta 的很多項目,例如Maven、 Torque等。
2.1. CheckStyle是什麼?
CheckStyle是SourceForge下的一個項目,提供了一個幫助JAVA開發人員遵守某些編碼規範的工具。它能夠自動化代碼規範檢查過程,從而使得開發人員從這項重要,但是枯燥的任務中解脫出來[1]。
2.2. CheckStyle檢驗的主要內容
CheckStyle默認提供一下主要檢查內容:

² Javadoc註釋
² 命名約定
² 標題
² Import語句
² 體積大小
² 空白
² 修飾符
² 塊
² 代碼問題
² 類設計
² 混合檢查(包活一些有用的比如非必須的System.out和printstackTrace)

從上面可以看出,CheckStyle提供了大部分功能都是對於代碼規範的檢查,而沒有提供象PMD和Jalopy那麼多的增強代碼質量和修改代碼的功能。但是,對於團隊開發,尤其是強調代碼規範的公司來說,它的功能已經足夠強大。
2.3. CheckStyle的主要運行方式
目前,CheckStyle的版本是3.0,與以前的版本不同,它的配置文件是基於XML而非Properties文件。

它的3.0版本提供了兩種運行的方式:

² 命令行工具
² ANT任務

同時,CheckStyle目前有很多針對流行IDE的插件,例如Eclipse、IntelliJ IDEA、JBuilder等。但是,大部分都是基於2.4的版本,新版本的特性不支持,同時配置也較爲複雜。

因爲一般情況下,如果與開發過程與環境集成起來,編碼規範的檢查會更加有效,因此,作爲ANT任務的運行方式使用的更加普遍。

在ANT的build.xml文件中添加CheckStyle任務的步驟如下:

1. 將checkstyle-all-3.1.jar拷貝到項目的LIB目錄;
2. 建立配置文件;
3. 聲明CheckStyle任務:
<taskdef resource="checkstyletask.properties"
classpath="${lib}/checkstyle-all-3.1.jar"/>
4. 建立CheckStyle任務:
<target name="checkstyle">
<checkstyle config="${config}/sun_checks.xml">
<fileset dir="${src}" includes=" **/*.java" />
</checkstyle>
</target>

2.4. 定製CheckStyle
CheckStyle的執行基於XML配置文件,它的主要組成部分是:

² Module:整個配置文件就是一棵Module樹。根節點是Checker Module。
² Properties:它來決定一個Module如何進行檢查。每個Module都有一個默認值,如果不滿足開發需求,可以設定其它的值。

下面是一個示例:

<module name="MethodLength">
<property name="max" value="60"/>
</module>

它表示,如果方法或者構造函數的長度超過60行,CheckStyle就會報錯。而默認值是150行。

以下是一段CheckStyle對於Maven項目源文件的檢查報告:

Method 'createExpression' is not designed for extension - needs to be abstract, final or empty. 91
Unable to get class information for JellyException. 91
Line has trailing spaces. 93
Line has trailing spaces. 104
Method 'evaluate' is not designed for extension - needs to be abstract, final or empty. 113
Parameter context should be final. 113
Line has trailing spaces. 130
Method 'getExpressionText' is not designed for extension - needs to be abstract, final or empty. 131
Line has trailing spaces. 134
Line has trailing spaces. 135
Method 'toString' is not designed for extension - needs to be abstract, final or empty. 137
Method 'isSupportAntVariables' is not designed for extension - needs to be abstract, final or empty. 156
Method 'setSupportAntVariables' is not designed for extension - needs to be abstract, final or empty. 168
Parameter supportAntVariables should be final. 168
'supportAntVariables' hides a field. 168
Method 'isValidAntVariableName' is not designed for extension - needs to be abstract, final or empty. 183
Parameter text should be final. 183

一般情況下,與IDE集成在一起使用的時候,點擊出錯的條目,可以跳轉到相應的代碼。
3. CheckStyle的最佳實踐
3.1. Sun’s Code Conventions的修改
在CheckStyle的最新發布版本中,有一個對於Sun的Java編碼規範的配置文件信息。但是,其中有很多條目並不一定符合項目開發的需要。就算是對於很多優秀的開源項目,按照這個規範來進行檢查,也會出現成千上萬的錯誤。

下面提出的一些修改意見,是從實際項目執行過程中總結出來的,可以作爲大家的參考。我們以CheckStyle3.0配置文件的順序來介紹:

1. 去除對於每個包都有一個package.html文件的限制;
<!--<module name="PackageHtml"/>-->
2. 修改對於JavaDoc Comments的限定:對於很多使用Code Generator的項目來說,需要將手寫代碼與生成代碼、單元測試代碼的檢查分開進行;
3. 修改對於體積大小的限制:目前,很多顯示器都是17寸,而且打印方面的限制也比以前有所改善,同時,由於代碼中Factory等模式的運用,以及有意義的方法名稱等約定,默認每行代碼的長度(80)是遠遠不能滿足要求;對於方法長度等等,也應該根據項目情況自行決定:
<module name="FileLength"/>
<module name="LineLength">
<property name="max" value="120"/>
</module>
<module name="MethodLength">
<property name="max" value="300"/>
</module>
<module name="ParameterNumber"/>
4. 修改對於Throws的的限制:允許Throws Unchecked Exception以及Throws Subclass Of Another Declared Exception。
<module name="RedundantThrows">
<property name="allowUnchecked" value="true"/>
<property name="allowSubclasses" value="true"/>
</module>
5. 修改成員變量的可視性:一般情況下,應該允許Protected Members以及Package Visible Members。
<module name="VisibilityModifier">
<property name="protectedAllowed" value="true"/>
<property name="packageAllowed" value="true"/>
</module>

3.2. CheckStyle應用的最佳實踐
採用CheckStyle以後,編碼規範的檢查就變得及其簡單,可以作爲一項切實可行的實踐加以執行。

一般情況下,在項目小組中引入CheckStyle可以按照下面的步驟進行:

1. 強調Code Review與Code Conventions的重要作用;
2. 介紹CheckStyle;
3. 初步應用CheckStyle:參照CheckStyle附帶的配置文件,酌情加以剪裁,在項目的Ant配置文件中,添加CheckStyle任務,可以單獨執行;
4. 修改、定型CheckStyle的配置文件:按照基本配置文件執行一段時間(2~3周),聽取開發人員的反饋意見,修改配置信息;
5. 作爲開發過程的日常實踐,強制執行CheckStyle:穩定CheckStyle的配置信息,同時將CheckStyle任務作爲Build的依賴任務或者配置源碼控制系統(目前,CheckStyle可以與CVS有效集成),使得代碼在加入系統之前必須通過檢查。

同時需要指出的是,CheckStyle的有效執行需要依賴兩個條件:

² Ant的廣泛應用:CheckStyle基於Ant執行的方式比較容易,而且可以在項目內容形成一致的執行環境。同時,也比較容易與其它任務,例如Build等發生關聯。

² IDE Format Code的強大功能:由於CheckStyle本身並沒有提供很強大的Code Format等功能,因此,需要藉助IDE的幫助,從而使得在發生錯誤的時候,可以很容易的進行修復。目前,主流的Java IDE都提供了這方面的功能,IDEA在這方面尤其突出。它提供的統一、可定義的Code Format Template(項目小組內部可以使用統一模板)以及方便的快捷鍵功能(Ctrl+Alt+T:Format Code, Ctrl+Alt+O:Optimize Import等)。

4. 結論
利用CheckStyle可以方便的對於編碼的Code Conventions進行檢查,同時,也有效地減少了Code Review的工作,使得Reviw人員的精力更多的集中到邏輯和性能檢查。

參考文獻:

[1] CheckStyle Project Website
[2] Code Review 理論與實戰 CSDN
[3] 輕鬆有效檢查Java代碼的三個工具 ZDNet China

發佈了49 篇原創文章 · 獲贊 8 · 訪問量 34萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章