七招掌控軟件的代碼質量
譯文【51CTO.com快譯】眾所周知,業界常把低質量的程序代碼稱為“技術債”。它們不但會影響軟件構建的效率,而且會在軟件交付和運行中,出現嚴重的服務質量問題。可見,軟件質量的重要性是不言而喻的。本文將和您討論在自動化的代碼質量控制流程中,有關代碼樣式、正確性、復雜度、設計、安全性、覆蓋率、以及審查等關鍵要素。
1.代碼的樣式
常言道:您的代碼觀感,直接反映了您對代碼的關心程度。此言不虛,即使是那些代碼段上的縮進不一致,也可能為代碼的后期分析帶來一場噩夢。更不用說由此產生的,不同開發團隊在聯調程序過程中的各種沖突了。
幸運的是,我們可以使用諸如Idea和Eclipse之類IDE工具,來自動化檢查代碼樣式的方式,進而修復并提高代碼的準確性。具體而言,開發團隊中的每個成員首先應當使用相同的代碼樣式定義,將其設置為共享的.editorconfig文件、或特定于某個IDE的配置之中。其次,我們需要通過將樣式檢查集成到構建的過程中,以確保每個成員都能遵循代碼樣式規則。我們可以在每次將代碼的更改推送到存儲庫時,通過Checkstyle的方式,采用Jenkins插件、Maven、以及Gradle的腳本來實現。
2.代碼的正確性
代碼掃描向來是一項耗時且繁瑣的工作,有時甚至難免有所疏漏。對此,我們可以使用一些免費的工具,其中包括:SpotBugs(它是已廢棄的FindBugs項目的繼承者)、PMD、Error Prone、以及SonarQube。其中的一些還可以識別出重復性的代碼,并發現潛在的性能問題。與Checkstyle相似,我們可以將這些工具集成到自己的IDE中,輕松地檢查出目標代碼中的缺陷。
此外,您也可以使用Checker Framework來增強Java系統的代碼檢查,以及防范潛在問題的能力。當然,您可能需要對其進行一些額外的手工配置。
值得注意的是,我們需要讓這些工具在項目構建的過程中就事先運行起來,以免在將代碼推送到存儲庫之前,忘記讓它們“把關”了。
3.代碼的復雜度
在前面的討論中,我們主要關注的是發現代碼中的常見編程缺陷。下面,讓我們聚焦代碼的復雜度。顯然,沒有人愿意閱讀和使用那些難以推理、維護和擴展的代碼。通常,我們可以使用如下指標,來衡量代碼的復雜度:
- Cyclomatic和NPath復雜度 — 是基于控制流的復雜度計算方法。換句話說,它顯示了在測試中,應當涵蓋的不同路徑的數量(可測試性)。我們可以使用的工具包括:Checkstyle、SpotBugs和PMD。
- 認知復雜度- 衡量的是代碼對于人類理解能力的難度(可讀性)。我們可以使用的工具包括:SonarQube和SonarLint的IDE插件。
4.代碼的設計
下面,讓我們來看看如何使用靜態代碼分析工具,來發現目標代碼在設計上的缺陷。目前,許多面向對象的設計實踐,都可以通過自動化的源檢查(source checks),以發現繼承層次(inheritance hierarchy)過高、以及上帝類(God class)等設計問題。對此,Checkstyle和PMD都提供了一整套檢查工具。其中包括:Source code file、Class、Method、以及Parameter list。它們都能夠根據基本設計規則,對代碼進行全面檢查。
除了上述基本的設計檢查,我們還可以通過如下靜態分析工具實現更深層次的檢查:
- PMD的LawOfDemeter可用于減少各個類之間的緊密耦合。
- Checkstyle的DesignForExtension,實現了由Joshua Bloch撰寫的《Java高效編程(Effective Java)》第三版的第17章:針對繼承或禁止繼承的設計和文檔(Design and document for inheritance or else prohibit it)。
- PMD的CouplingBetweenObjects,通過唯一屬性、局部變量、以及返回類型的數量等信息,來檢測難以測試、分析和擴展的緊密耦合類。
- jPeek,可衡量類的內聚性,進而保持各種類、模塊、以及包的高內聚性。
- embold,包含了大量針對耦合和內聚的有關高級設計缺陷的檢查功能。
- CodeScene是從開源項目Code Maat處演變而來的。通過分析版本控制系統中有關歷史代碼的更改,它不僅可以發現潛在的設計問題,還能夠發現開發中的瓶頸問題。
值得注意的是,最后兩款工具僅對于開源項目是免費的。
5.代碼的安全性
在開發過程中,為了確保代碼的安全性、可擴展性、以及可維護性,我們需要持續檢索CVE數據庫,以避免第三方的依賴項出現安全漏洞。此外,您也可以從如下資源處獲取有關代碼安全的各種實踐:
- 通用安全編碼規則--OWASP TOP 10
- 特定技術安全編碼規則--Oracle Java的安全編碼準則
- 最常見的安全漏洞--Mitre CWE Top 25,SANS TOP 25
作為補充,下面是幾種具有自動化執行功能的,代碼安全性檢查工具:
- FindSecBugs,是SpotBugs的插件,可用于審核Web應用中Java程序的安全性。您不但可以將其集成到Maven或Gradle之類的構建過程中,還可以在使用IDE插件進行編碼時用到它。
- SonarQube是一個多合一的安全性檢查工具。其母公司SonarSource在2020年收購了RIPS Technologies后,進一步提升了Sonar的安全檢測能力。
此外,各種第三方的依賴項和Docker鏡像,也能夠在代碼質量控制的過程中,實現各項安全性的掃描。
6.代碼的覆蓋率
常言道:如果沒有大量的自動化測試,就無法驗證代碼是否能夠按期運行;如果沒有自動化的回歸測試,就無法安全地重構代碼。那么,我們又該如何在保證具有高質量的代碼置信度的基礎上,盡可能涵括更多的流程,檢查并提高代碼的覆蓋率呢?顯然,我們需要事先充分地準備好如下不同的測試覆蓋率相關指標:
- 語句與指令的覆蓋率,即:程序中有多少條語句已被執行。
- 代碼行覆蓋率,即:已測試了多少行源代碼。
- 分支覆蓋率,即:已經執行了目標控制結構中的多少個分支。
- 方法與功能覆蓋率,即:定義了多少種方法。
在工具方面,我們可以使用IntelliJ IDEA的Coverage、Eclipse的JaCoCo等具有IDE的流行工具。
- 通過將Coverage工具集成到構建過程中,我們能夠通過上述指標,來了解具體涵蓋了代碼的哪些部分,進而發現測試中的不足。
- JaCoCo可謂Java領域最流行的代碼覆蓋率工具。您可以通過Maven、Gradle、甚至是Ant,將其集成到構建的過程中。JaCoCo既提供了開箱即用式的支持,又可以從遠程流程中收集到覆蓋率的相關信息。同時,它也能協助我們將端到端的測試,包括在代碼覆蓋率的最終報告中。值得一提的是,Sonar也使用JaCoCo來監控那些隨時間變化的代碼覆蓋率。您還可以針對新的代碼覆蓋率級別過低的情況,自定義質量門(Quality Gates)的通知與警報。
- OpenClover除了提供一組基本的覆蓋率度量標準與集成之外,還包含了一組旨在提高代碼覆蓋率的度量標準。
- Cobertura曾經是Java最受歡迎的代碼覆蓋工具,不過目前已不再被維護與更新。
7.半自動化的代碼審查
在整個代碼管控的過程中,最復雜、且最難實現自動化的環節,當屬代碼審查。由于部分需要依賴手動來實現,因此該過程往往取決于審查者的技能、資歷、甚至是態度,而且其結果也不盡相同。
例如,SonarQube僅在其付費版本中,提供了針對合并與拉取式請求的靜態自動化分析。據此,您可以在打開某個合并式請求(Merge Request)時,登錄到SCM,并在代碼中直接查看到靜態代碼分析的結果。
而開發人員則主要會從如下方面開展代碼審查:
- 功能性需求審查
- 特定項目的需求審查
- 高級設計或架構審查
- 代碼復雜度和性能審查
因此,為了使代碼審查的過程更能保持一致性,我們應準備好一份代碼審查清單,以事先約定好手動代碼驗證的詳細內容。對此,您可以參考Google的《代碼審查之開發者指南,Code Review Developers Guide》。它在“代碼審查”部分給出了一個簡短的審查清單,以便實現整個團隊在審查過程中的統一性。
原文標題:How To Keep Code Quality Under Control In 7 Steps,作者:Artur Kluz
【51CTO譯稿,合作站點轉載請注明原文譯者和出處為51CTO.com】