你的代碼寫得怎麼樣?如果你不屬於平庸的 80%,我敢打賭你的代碼一定寫得很棒。也許你正在維護遺產代碼(不再被廣泛支持的系統相關的源代碼),這些代碼究竟能有多糟糕?情況會有所好轉嗎?雖然有一套方法可以幫助評估你的代碼,然而並非每個人都對此表示認可。
優點
我個人認為評估數據非常有用。通過類似 Emma 這樣代碼覆蓋率計算工具,能夠讓你徹底瞭解你的代碼中究竟哪些已經被測試覆蓋,還有哪些沒有被測試到。在開始著手某個包進行大規模代碼重構之前,目標代碼 的覆蓋率究竟如何?這些信息會告訴我,也許應該在改動代碼前先提高一下這部分的代碼覆蓋率。
代碼行數是另一個種有意思的數據。當你在遺產代碼上工作的時候(誰不是在這樣的代碼上工作呢),如果你既能夠保持開發速度(你肯定還在開發新的功 能),又能保持與過去相同甚至更少的代碼,那麼你不但能夠在交付價值而且同時還能讓代碼變得不那麼糟糕。任何一個傻瓜都能夠寫出成堆的新代碼以完成新功 能,但是真正的高手能夠在交付新功能的同時減少原有的代碼。
缺點
任何數據都會面對一個問題,那就是利用這些數據的人。你最不想看到的恐怕就是過度渴望監控這些數據的經理了。
不能度量就無法控制。– Tom DeMarco
在你得到數據之前,報告缺陷數量就已經和獎金掛鉤了。還有可能大家都希望代碼覆蓋率能夠達到某個「期望值」。
只要管理層用數據作為目標,聰明人就會利用系統作弊。我已經數不清有多少次看到人們對代碼覆蓋率造假了。雖然初衷很好,但經理們受到錯誤思想的誤 導。為了討經理開心,開發者會不斷編寫沒有斷言的測試。當然,代碼依然能夠運行而且不會出什麼大問題。但這種行為有意義嗎?天知道!當你的代碼引入了新 bug,那些測試能夠檢測到嗎?見鬼,當然不會!因此,這種代碼覆蓋率毫無用處。
儘管達到了指標,但是潛在的目標即改進軟件質量卻被忽視了,而且未來也不會達到。
醜陋之處
任何評估的目標都是評測代碼並從中得出有意義的數據。以代碼覆蓋率為例,我們真正感興趣的是缺陷覆蓋率。也就是代碼中的所有可能的缺陷,有多少缺陷能夠在測試中被發現?我們想知道,能夠在怎樣的程度上能夠避免重寫代碼。
問題在於,我怎樣才能衡量一個系統中「所有可能的缺陷」?基本上這是不可能知道的。為此,我們使用代碼覆蓋率作為近似。考慮到測試能夠保證代碼運行 得到正確的結果,因此被執行代碼率是對能夠捕捉到 bug 數量的一個很好的預測。如果我的測試執行了 50% 的代碼,最好的情況下我們能夠捕捉到 50% 的 bug。如果 bug 出現在另外 50% 的代碼中,那麼通過我的測試捕捉到這些 bug 的幾率為0.代碼覆蓋率是測試覆蓋率的一個上限。但假如你的測試代碼很差,那麼相應的測試覆蓋率也會降低。至於沒有斷言的測試代碼,它們基本上毫無用處。
這就是測量數據困難之處:測量那些真正管用的數據即我們的軟件的質量。即便有可能,也是非常困難的。因此,我們要儘可能地進行測量,但並不總是能夠清晰地知道哪些內容與我們真正目標相關。
這些數據意味著什麼?
有很多類似 Sonar 這樣的優秀工具能為你的代碼進行各種常用的數據評測。通常的問題在於,開發者並不瞭解(或者在意)這些數據的含義。類的複雜度是 17.0 是好還是壞?我的代碼關聯繫數是5.6%,但是也許有更好的理由這麼做。怎樣的數據對這段代碼而言才算是合理的?LCOM4(缺乏內聚性的方法指標)是好 事還是壞事?坦率的說,這聽起來更像是治療癌症。
當然,如果我足夠積極主動的話,我應該能夠深入並且瞭解每種數據的含義,並且試著達成合理的目標,等等等等。拜託,我正忙著給客戶交付有價值的工作,沒有時間扯淡。這些數據是在讓人難以捉摸,索性忽略掉好了。當然,領導們不這麼認為。
一種更好的辦法
一定有一種更好的辦法來評估「代碼質量」。
1. 達成一致
無論你評估的是什麼,評估的內容一定要得到團隊成員的贊同和理解。如果團隊中有一半的人表示反對,那麼評估的結果一定不會很好。一些人努力想要改進,而其餘的人則會讓事情變得糟糕。實際效果一定會讓人大失所望。
2. 評估最重要的部分
不必評估「標準」的內容,像是代碼覆蓋率或者圈複雜度。只要團隊成員一致認為這是一項有用的數據,每個人都認為需要在這個方面改進並且做出承諾,那麼評估它就是有用的。
我在 youDevise 的一個同事,花了 10% 的工作時間構建了一個可以跟蹤評估數據並能夠以圖形的方式展示結果的工具。然而,非常特別的是,這個工具並沒有計算很多大型靜態分析工具給出的那些常見評 估數據,而更多地統計了更加常見和具體的問題。那麼,哪些是更貼近自己且更容易評估的呢?
· 如果你有一個上帝類,那麼可以統計文件的代碼行數,行數越少越好
· 如果你有一個想要避免使用的第三方函數庫,那麼可以統計使用它的次數
· 如果你有一個想要移除的類,那麼可以統計引入這個類的次數
這些簡單的測量代表了我們真正想要擺脫的技術債務,通過減少技術債務我們能夠改進自己代碼的質量。與此同時,評估的方法也會異常的簡單,最直接的方式只需要執行 grep 和 wc 命令就可以。
評估什麼並不重要,只要團隊相信你評估這些內容會得到改進。通過評估你們關心的內容,你會真正瞭解到你的代碼質量。
3. 讓結果更直觀
最後,請把評估結果貼到顯示器上,與實際構建狀態越接近越好。這樣每個人都能夠看到你正在做什麼,並且能夠不斷提醒人們質量的重要性。反饋是非常重要的,你能夠看到事情正在朝著更好的方向發展;同樣重要的是,當質量開始滑坡時,數據圖能夠把問題上升的趨勢展示出來。
簡單,明了
代碼質量是一個非常抽象的概念,因而很難測量。因此,你應當轉而關注那些容易評估的東西。評估內容越簡單、越容易理解,改進起來也越容易。如果你需 要花時間解釋這些評估的意義,那麼這裡肯定有問題。嘗試一次只關注一部分內容,如果你同時關注 100 項不同的數據,讓這些方面都能夠得到改進幾乎是不可能的。如果我們只關注其中的幾項,我就能記住他們,至少不會讓它們變得更差。我有可能把它們清晰的記下 來,這樣才能夠改進它們。
你在評估自己的代碼嗎?如果是的,你評估的內容是什麼?如果不是,你認為可以評估哪些方面呢?