代碼異味

代碼異味

在計算機編程中,代碼氣味是程式原始碼中可能表示更深層問題的任何特徵。確定什麼是代碼味道和不是代碼味道是主觀的,並且因語言,開發人員和開發方法而異。

這個詞在20世紀90年代後期由Kent Beck在WardsWiki上推廣。 在“重構:改進現有代碼的設計”一書中,Martin Fowler將該術語的用法增加了。它也是敏捷程式設計師使用的術語。

基本介紹

  • 中文名:代碼異味
  • 外文名:Code smell
  • 定義:代碼中導致深層次問題的症狀
  • 詞性:編程名詞
簡介,常見的代碼異味,

簡介

程式開發領域,代碼中的任何可能導致深層次問題的症狀都可以叫做代碼異味。通常,在對代碼做簡短的反饋疊代時,代碼異味會暴露出一些深層次的問題,這裡的反饋疊代,是指以一種小範圍的、可控的方式重構代碼。基於這些暴露的問題,人們會進一步的檢查設計和代碼中是否還存在別的代碼異味,然後再做進一步的重構。從負責重構的開發者的角度來看,代碼異味可以啟發何時重構,如何重構。因此,可以說代碼異味推動著重構的進行。
該術語似乎由Kent Beck於90年代後期,在WardsWiki上首次使用。且自從在Refactoring. Improving the Design of Existing Code.被提到過,使用率就大大的提高。代碼異味同時也是敏捷開發者常用的術語。
什麼是,或者不是代碼異味,是一個主觀的判斷,通常因語言、開發者、開發方法的不同而不同。對於Java開發語言,有些工具,比如Checkstyle、PMD和 FindBugs可以自動檢測一些代碼異味。
查看氣味的一種方法是關於原則和質量:“氣味是代碼中的某些結構,表明違反基本設計原則並對設計質量產生負面影響”。代碼味道通常不是錯誤;它們在技術上不正確,並且不會阻止程式運行。相反,它們表明設計中的弱點可能會減緩開發速度或增加未來的漏洞或故障風險。不良代碼氣味可能是導致技術債務的因素的指標。羅伯特·C·馬丁(Robert C. Martin)稱一系列代碼聞起來是軟體工藝的“價值體系”。
當代碼經歷一個短的反饋循環時,通常可以發現代碼氣味所暗示的更深層次的問題,在那裡以小的,受控的步驟進行重構,並檢查所得到的設計以查看是否還有任何代碼味道反過來表明需要更多的重構。從負責執行重構的程式設計師的角度來看,代碼氣味是指示何時重構的啟發式方法,以及使用什麼特定的重構技術。因此,代碼氣味是重構的驅動因素。
2015年的一項研究利用自動化分析對50萬個原始碼提交進行了手動檢查,並對9,164個確定顯示“代碼味道”的提交進行了手工檢查,結果發現:
對於“技術債務”的後果存在經驗證據,但是只存在關於這種情況發生的方式,時間或原因的軼事證據。
“普遍的觀點表明,緊急維護活動和提供功能的壓力,同時優先考慮產品上市時間而不是代碼質量通常是造成這種氣味的原因”。
有一些工具,如Checkstyle,PMD和FindBugs for Java原始碼,可以自動檢查某些類型的代碼氣味。

常見的代碼異味

套用級氣味:
  • Duplicated code:相同或非常相似的代碼存在於多個位置。
  • 複雜性:強制使用過於簡單的設計模式,簡單的設計就足夠了。
  • Shotgun surgery:需要同時對多個班級進行單一更改。
類級氣味:
大類:一個已經變得太大的類。
  • Feature envy:一個過分使用另一個類的方法的類。
  • Inappropriate intimacy:一個依賴於另一個類的實現細節的類。
  • Refused bequest:一個覆蓋基類方法的類,其方式是派生類不遵守基類的約定。見Liskov替代原則。
  • Lazy類/ freeloader:一個做得太少的類。
  • 過度使用文字:這些文字應編碼為命名常量,以提高可讀性並避免編程錯誤。此外,文字可以並且應該儘可能地外化到資源檔案/腳本中,以便在軟體旨在部署在不同區域時促進軟體的本地化。
  • Cyclomatic複雜性:分支或循環太多;這可能表明功能需要分解為更小的功能,或者它具有簡化的潛力。
  • 向下轉換:打破抽象模型的類型轉換;抽象可能必須重構或消除。
  • 孤立變數或常量類:通常具有常量集合的類,這些常量屬於其他位置,其中這些常量應由其他成員類之一擁有。
  • 數據塊:當一組變數在程式的各個部分中一起傳遞時發生。一般來說,這表明將形式上將不同變數組合成一個對象更合適,而只是傳遞這個對象。
方法級氣味:
  • 參數太多:很難讀取很長的參數列表,並使調用和測試函式變得複雜。它可能表明該功能的目的是錯誤的,並且應該重構代碼,以便以更清晰的方式分配責任。
  • 長方法:方法,功能或過程變得過大。
  • 標識符過長:特別是使用命名約定來提供應該隱含在軟體體系結構中的消歧。
  • 標識符過短:變數名稱應反映其功能,除非功能明顯。
  • 過度返回數據:返回超過每個調用者所需內容的函式或方法。
  • 過長的代碼行(或上帝行):代碼行很長,使得代碼難以閱讀,理解,調試,重構甚至識別軟體重用的可能性。例:
new XYZ(s).doSomething(buildParam1(x), buildParam2(x), buildParam3(x), a + Math.sin(x)*Math.tan(x*y + z)).doAnythingElse().build().sendRequest();

相關詞條

熱門詞條

聯絡我們