軟件開發(fā)始于需求卻不能終于需求,我們?cè)跐M足需求的同時(shí),還需要考慮代碼本身的質(zhì)量,包括可讀性、可維護(hù)性、可擴(kuò)展性、可移植性、安全性、高效性等。
上一篇文章《汽車軟件單元測(cè)試的要點(diǎn)與意義》提到了諸如靜態(tài)分析與覆蓋度測(cè)試的一些代碼評(píng)價(jià)手段,這一篇講一些具體指標(biāo)。
這些指標(biāo)主要來自于ASIL D軟件的實(shí)踐經(jīng)驗(yàn)。
1
每個(gè)函數(shù)的語句數(shù)
該指標(biāo)是指函數(shù)內(nèi)部語句的個(gè)數(shù),是一種基礎(chǔ)的代碼復(fù)雜度度量方式。在多數(shù)語言中,我們可以使用工具自動(dòng)計(jì)算語句個(gè)數(shù)。
常見語句包含以下類型:
以分號(hào)(;)結(jié)尾的簡(jiǎn)單語句
語句個(gè)數(shù)應(yīng)盡量維持在10~20,最多不要超過50。
2
return語句的數(shù)量
為了提高代碼的可讀性,我們最好遵循“單一出口原則”,也就是盡量保證一個(gè)函數(shù)只有一個(gè)出口點(diǎn)(函數(shù)結(jié)束執(zhí)行的地方)。
出口點(diǎn)通常是return語句,所以我們也建議盡量減少其數(shù)量,比如,一個(gè)函數(shù)的return維持在1~2個(gè)之內(nèi)。
3
代碼行長(zhǎng)度
寫文章要短句,是為了便于閱讀。代碼也是一樣,太長(zhǎng)的代碼行會(huì)明顯增加閱讀代碼的難度,很現(xiàn)實(shí)的問題是,需要開發(fā)人員左右滾動(dòng)屏幕。
在保證合理的邏輯、換行和縮進(jìn)的前提下,要盡可能將長(zhǎng)代碼拆分。通常,低于160個(gè)字符的代碼行可以認(rèn)為是一個(gè)合理目標(biāo)。
4
圈復(fù)雜度
圈復(fù)雜度是指通過源代碼線性獨(dú)立路徑的個(gè)數(shù),也是用來衡量代碼復(fù)雜度。
如何計(jì)算呢?我們可以通過以下3個(gè)代碼控制流圖來看。
一種計(jì)算公式為,圈復(fù)雜度M=控制流圖邊數(shù)E-節(jié)點(diǎn)N+2
故,
圖1:M=1-2+2=1,即無判定節(jié)點(diǎn),圈復(fù)雜度為1。
圖2:M=4-4+2=2,即一個(gè)判定節(jié)點(diǎn),圈復(fù)雜度為2。
圖3:M=7-6+2=3,即兩個(gè)判定節(jié)點(diǎn),圈復(fù)雜度為3。
除了評(píng)價(jià)本身代碼判定邏輯的復(fù)雜性之外,圈復(fù)雜度還能夠用來確定最少需要多少個(gè)測(cè)試用例來滿足分支和路徑的覆蓋度。
一般經(jīng)驗(yàn)是,圈復(fù)雜度應(yīng)小于10,以達(dá)到較好的可測(cè)性。
5
非循環(huán)路徑數(shù)
這個(gè)指標(biāo)也被稱為NPATH,是指通過軟件所有可能路徑的數(shù)量。其中,循環(huán)中的循環(huán)(for, while, do-while)只訪問一次。
因此,NPATH也給出了達(dá)到路徑覆蓋所需的測(cè)試用例的最大數(shù)量。而圈復(fù)雜度給出了測(cè)試用例的最小數(shù)量。
如下圖,對(duì)應(yīng)的圈復(fù)雜度和NPATH分別為2和4。NPATH建議限制在80個(gè)以內(nèi)。
6
每個(gè)函數(shù)的嵌套級(jí)別
嵌套級(jí)別用來描述函數(shù)之間調(diào)用的深度層次。
當(dāng)引入控制結(jié)構(gòu)(if, while…)時(shí),就會(huì)發(fā)生嵌套,每將控制結(jié)構(gòu)放置在其他控制結(jié)構(gòu)內(nèi)部一次,嵌套級(jí)別就會(huì)增加一次。
以下為一個(gè)嵌套級(jí)別為2的代碼段示意。
if(a < K) {
if(b > L) {
function);
}
}
嵌套級(jí)別建議不超過4。
7
調(diào)用圖遞歸
調(diào)用圖是軟件工程中用于表示函數(shù)調(diào)用關(guān)系的有向圖,它顯示了哪個(gè)函數(shù)調(diào)用了哪個(gè)函數(shù)。
調(diào)用圖內(nèi)部的遞歸是一個(gè)函數(shù)直接或間接(通過至少一個(gè)其他函數(shù))再次調(diào)用自身的模式。
遞歸是一種很好的編程技巧,但在嵌入式中有一些缺點(diǎn)。
要想停止遞歸時(shí),必須有一個(gè)結(jié)束條件,否則,遞歸將導(dǎo)致應(yīng)用程序崩潰,但是,無論是直接遞歸還是間接遞歸,確定結(jié)束條件并不容易。
此外,由于遞歸算法需要更多的函數(shù)調(diào)用和堆棧操作,其使用會(huì)造成性能阻塞、可讀性差或堆棧溢出等問題。
一般不建議使用遞歸。
8
不同函數(shù)的調(diào)用次數(shù)
更多的函數(shù)調(diào)用必然帶來更大的復(fù)雜性,整體最好不超過7次。
9
參數(shù)數(shù)量
參數(shù)的數(shù)量是函數(shù)復(fù)雜性和接口復(fù)雜性的另一個(gè)指標(biāo)。存在的參數(shù)越多,就越容易在調(diào)用函數(shù)時(shí)出錯(cuò),比如,參數(shù)順序錯(cuò)誤。
如果函數(shù)參數(shù)超過了5個(gè),可以試著把函數(shù)分成使用較少參數(shù)的邏輯部分。
10
goto語句
goto語句可以使程序直接跳轉(zhuǎn)到同一函數(shù)中的預(yù)定義位置。
goto是一個(gè)很有爭(zhēng)議的語句。在處理錯(cuò)誤或跳出多層循環(huán)時(shí),有很直接的效果,但非邏輯性的跳轉(zhuǎn)會(huì)讓代碼很難理解、出了錯(cuò)誤也很難追蹤。
所以,通常強(qiáng)烈建議不要使用goto語句。
11
注釋密度
除了從語句結(jié)構(gòu)上降低外,代碼復(fù)雜度還有一種應(yīng)對(duì)方式是代碼注釋。
函數(shù)功能的文本化描述就是注釋,這顯然有助于理解代碼。特別地,代碼已經(jīng)長(zhǎng)時(shí)間沒有被修改,或者代碼必須由原始編寫人分析或修改時(shí),這些注釋更加有用。
一種算法是,注釋密度是指第一個(gè)語句之后找到的注釋數(shù)量與語句數(shù)量之間的比率,20%是一個(gè)可參考的下限。
審核編輯:黃飛
-
嵌入式
+關(guān)注
關(guān)注
5060文章
18975瀏覽量
302211 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4285瀏覽量
62333
原文標(biāo)題:評(píng)價(jià)ASIL D軟件代碼的11個(gè)指標(biāo)
文章出處:【微信號(hào):eng2mot,微信公眾號(hào):汽車ECU開發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論