一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

代碼質量概述

一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

.

代碼質量所涉及的5個方面:

  • 編碼標準
  • 代碼重複
  • 代碼覆蓋率
  • 依賴項分析
  • 複雜度分析

這5方面很大程序上決定了一份代碼的質量高低。我們分別來看一下這5方面:

  • 編碼標準:這個想必都很清楚,每個公司幾乎都有一份編碼規範,類命名、包命名、代碼風格之類的東西都屬於其中。
  • 代碼重複:顧名思義就是重複的代碼,如果你的代碼中有大量的重複代碼,你就要考慮是否將重複的代碼提取出來,封裝成一個公共的方法或者組件。
  • 代碼覆蓋率
    :測試代碼能運行到的代碼比率,你的代碼經過了單元測試了嗎?是不是每個方法都進行了測試,代碼覆蓋率是多少?這關係到你的代碼的功能性和穩定性。
  • 依賴項分析:你的代碼依賴關係怎麼樣?耦合關係怎麼樣?是否有循環依賴?是否符合高內聚低耦合的原則?通過依賴項分析可以辨別一二。
  • 複雜度分析:以前有人寫的程序嵌套了10層 if else你信嗎?圈複雜度之高,讓人難以閱讀。通過複雜度分析可以揪出這些代碼,要相信越優秀的代碼,越容易讀懂。

上面解釋了代碼質量相關的5個方面,在實際開發環境中,已經有很多工具為我們解決以上5個方面的問題,下列5個eclipse插件分別對這5個問題有很好的支持:

  1. 編碼標準:CheckStyle 插件URL://eclipse-cs.sourceforge.net/update/
  2. 代碼重複:PMD的CPD 插件URL://pmd.sourceforge.net/eclipse/
  3. 代碼覆蓋率:Eclemma 插件URL://update.eclemma.org
  4. 依賴項分析:JDepend 插件URL://andrei.gmxhome.de/eclipse/
  5. 複雜度分析:Eclipse Metric 插件URL://metrics.sourceforge.net/update

編碼標準(CheckStyle的使用)

在eclipse上安裝好了CheckStyle插件後,我們來建一個類用它跑一下。這個類很簡單,一個常見的用戶實體,包含了id,用戶名、密碼、郵件等屬性,幷包含get set方法,一個標準的POJO。運行CheckStyle檢查一下:

一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

.

一個我們平時再普通不過的一個類,被checkstyle弄出這麼多問題,情何以堪,我們來看看究竟是什麼情況?

看一下這些警告信息:

line 1、

一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

.

,說缺少package-info.java文件。

line 2、

一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

.

,說第一句註釋要以“.”結尾。

line 30、

一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

.

,缺少java doc註釋。

line 35、

一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

.

getId不是繼承的方法,必須指定abstract,final或空。另外也缺少java doc註釋。

這個類基本就這四類毛病,缺少package-info.java文件,這個文件是做什麼的呢?他是用來描述包註釋的類,有一定的特殊性,要想詳細瞭解請百度。如果對你的項目沒有太大的影響,可以忽略它。配置CheckStyle的方法我們等會再說。第一句註釋要以“.”結尾,這看你的習慣,你確定需要這個,你就保留,不需要就忽略。缺少java doc,對於java類的屬性來說,註釋是必要的,所以這個要保留。不是繼承的方法,需要加上final關鍵字,如果你有這個習慣,就保留,反之忽略。

我們這裡只是建立了一個最簡單的類用CheckStyle來檢查,隨著你的類代碼越來越多,邏輯越來越複雜,CheckStyle能檢查出來的毛病也越來越多。常見的CheckStyle錯誤有這些:

1.Type is missing a javadoc commentClass

缺少類型說明

2.“{” should be on the previous line

“{” 應該位於前一行

3.Methods is missing a javadoc comment

方法前面缺少javadoc註釋

4.Expected @throws tag for “Exception”

在註釋中希望有@throws的說明

5.“.” Is preceeded with whitespace “.”

前面不能有空格

6.“.” Is followed by whitespace“.”

後面不能有空格

7.“=” is not preceeded with whitespace

“=” 前面缺少空格

8.“=” is not followed with whitespace

“=” 後面缺少空格

9.“}” should be on the same line

“}” 應該與下條語句位於同一行

10.Unused @param tag for “unused”

沒有參數“unused”,不需註釋

11.Variable “CA” missing javadoc

變量“CA”缺少javadoc註釋

12.Line longer than 80characters

行長度超過80

13.Line contains a tab character

行含有”tab” 字符

14.Redundant “Public” modifier

冗餘的“public” modifier

15.Final modifier out of order with the JSL

suggestionFinal modifier的順序錯誤

16.Avoid using the “.*” form of import

Import格式避免使用“.*”

17.Redundant import from the same package

從同一個包中Import內容

18.Unused import-java.util.list

Import進來的java.util.list沒有被使用

19.Duplicate import to line 13

重複Import同一個內容

20.Import from illegal package

從非法包中 Import內容

21.“while” construct must use “{}”

“while” 語句缺少“{}”

22.Variable “sTest1” must be private and have accessor method

變量“sTest1”應該是private的,並且有調用它的方法

23.Variable “ABC” must match pattern “^[a-z][a-zA-Z0-9]*$”

變量“ABC”不符合命名規則“^[a-z][a-zA-Z0-9]*$”

24.“(” is followed by whitespace

“(” 後面不能有空格

25.“)” is proceeded by whitespace

“)” 前面不能有空格

可以看出CheckStyle檢查出來的問題,大多是編碼規則以及風格上的問題,這是編寫高質量代碼最基本的。值得注意的是,我們將一些優秀的開源代碼用CheckStyle來檢查也會檢查出不少問題,這不能不說這些開源不優秀,而是每個公司組織有自己的編寫規範度,這個度既可以減少程序員的工作量又可以讓代碼的可讀性合格,但這個度不一樣符合CheckStyle的完整標準。所以我們一般使用CheckStyle都不會用他的默認標準,而是通過配置,制定適合自己的編碼規則。

自定義CheckStyle規則:

一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

.

打開CheckStyle配置,新建一個配置,選擇外部配置文件。在這之前最好導出一個eclipse自帶的checkstyle配置文件(sun_checks.xml),然後重命名作為一個外部的配置導進去,這麼做的目的是導入之後可以修改相應的配置,達到自定義配置的目的(因為eclipse自帶的配置是加鎖的,不能修改)。導入之後,點擊右邊的“Configure”進行編輯。

先去掉缺少package-info.java文件的提示

一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

.

再將第一句註釋要以“.”結尾這個規則去掉,雙擊“Style javadoc”,將窗口內“checkFirstSentence”勾選去掉。

一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

.

對於實體類,屬性有了註釋,get set方法也不需要註釋了,雙擊“Method javadoc”將allowMissingPropertyJavadoc勾選中。

一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

.

“getId不是繼承的方法,必須指定abstract,final或空”,如果你懶得在方法上加“final”,這條規則也可以去掉。

一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

.

如果你不想每一個參數都加“final”,還需要把參數的final規則去掉:

一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

.

另外還有一個錯誤“’id’ hides a field.”,原因是方法的參數和類裡面定義的域重名了,但使用eclipse生成的get set方法都會這樣,所以可以忽略此項。

一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

.

至此我們再使用checkstyle檢查一篇,發現僅剩下屬性缺少註釋這個警告。

一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

.

對每個屬性加上java doc註釋,所有問題都清除了。以此類推,解決checkstyle問題的方法就是:1、按規則解決代碼問題;2、如果覺得這個問題對你的項目質量影響不大,則可以忽略它。

代碼重複(PMD的CPD的使用)

對於多人開發的項目,難以避免出現重複代碼的問題,儘管我們儘量對共用的代碼進行了封裝,但隨著需求的增加、人員技術水平差異、溝通不足等原因,重複代碼會越來越多。這不僅嚴重影響代碼質量,也無形中增加了代碼量。

注:精簡的程序和高複用度的代碼是我們一直追求的目標。

PMD的CPD工具就是為檢查重複代碼而生的。右鍵項目—>PMD—->Find Suspect Cut and Paste,執行重複代碼檢查:

一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

.

檢查出來的重複代碼,可以雙擊查看。然後根據業務邏輯以及代碼特徵,決定要不要做封裝、怎麼封裝。

代碼覆蓋率(Eclemma的使用)

一份質量合格的代碼,不僅包含功能程序本身也包含了對應的測試代碼,Eclemma插件可以用來統計測試代碼覆蓋整體代碼中的比率,以此來評估代碼的功能性和穩定性。

使用Junit編寫好測試用例之後,右鍵Coverage As—>Junit Test,運行測試用例,Eclemma會統計出相關的代碼覆蓋率:

一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

.

根據這個結果,你可以看出自己編寫的測試用例覆蓋到了那些代碼,而沒有覆蓋到的代碼,則有可能成為代碼質量的盲區。

依賴項分析(JDepend的使用)

隨著程序業務邏輯的增加,代碼的依賴關係也變的越來越複雜,JDepend插件可以統計包和類的依賴關係,分析出程序的穩定性、抽象性和是否存在循環依賴的問題。右鍵包—>Run JDepend Analysis:

一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

.

看一下這幾項指標:

CC(Number of Classes)

被分析package的具體和抽象類(和接口)的數量,用於衡量package的可擴展性。如果一個類中實現了其他類,如實現了監聽類,則監聽類的數目也記錄在此。

AC(Abstract classes)

抽象類和接口的數量。

Ca(Afferent Couplings)

依賴於被分析package的其他package的數量,用於衡量pacakge的職責。即有多少包調用了它。

Ce(Efferent Couplings)

被分析package的類所依賴的其他package的數量,用於衡量package的獨立性。即它調用了多少其他包。

A(Abstractness)

被分析package中的抽象類和接口與所在package所有類數量的比例,取值範圍為0-1。

I(Instability)

I=Ce/(Ce+Ca),用於衡量package的不穩定性,取值範圍為0-1。I=0表示最穩定,I=1表示最不穩定。即如果這個類不調用任何其他包,則它是最穩定的。

D(Distance)

被分析package和理想曲線A+I=1的垂直距離,用於衡量package在穩定性和抽象性之間的平衡。理想的package要麼完全是抽象類和穩定(x=0,y=1),要麼完全是具體類和不穩定(x=1,y=0)。取值範圍為0-1,D=0表示完全符合理想標準,D=1表示package最大程度地偏離了理想標準。即你的包要麼全是接口,不調用任何其他包(完全是抽象類和穩定),要麼是具體類,不被任何其他包調用。

Cycle

循環依賴的數量。

有個這個報告我們就可以有針對性的對代碼進行設計和重構。

複雜度分析(Metrics的使用)

對於閱讀代碼的人來說,越簡單的代碼越好理解和維護,如果你的代碼閱讀起來很費勁或者你自己過段時間後再來看都看不懂,你就得想辦法解決下代碼的複雜度問題了。Metrics插件可以幫你做到這點。

首先在Java透視圖下右鍵一個項目—->Properties,選擇Metrics,勾選Enble Metrics。

一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

.

然後Window—>Show View—->Other—->Metrics View

一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

.

打開Metrics視圖,點擊右上角運行圖標,即可得到複雜度分析的結果:

一個合格程序猿的代碼規整之旅,慢慢收集,路漫漫其修遠兮!

.

可以根據複雜度指標,對自己的程序進行優化。

小結

本文介紹了和java代碼質量相關的5個方面問題,並介紹對應eclipse插件的用法和作用。在我們實際開發中,儘量根據自己公司和團隊的情況來制定一些檢查規則,來提高代碼質量。並且在大多數情況下,會有兩個檢查環節,即本地檢查和持續集成環境的檢查,我們常用的Hudson就可以集成很多插件。


分享到:


相關文章: