1 代碼結(jié)構(gòu)分析概述
在編寫(xiě)代碼時(shí),要求要結(jié)構(gòu)清晰、接口簡(jiǎn)單。如果代碼結(jié)構(gòu)過(guò)于復(fù)雜,會(huì)帶來(lái)很多問(wèn)題:代碼很難被理解,不方便編寫(xiě)測(cè)試用例,容易隱藏錯(cuò)誤,出現(xiàn)問(wèn)題難以定位,修改代碼容易產(chǎn)生新的Bug等等。因此,需要有一些指標(biāo)來(lái)評(píng)估代碼的復(fù)雜度,以方便對(duì)過(guò)于復(fù)雜的代碼進(jìn)行重構(gòu)。
代碼的復(fù)雜度通??赏ㄟ^(guò)以下幾個(gè)指標(biāo)來(lái)評(píng)估:
(資料圖片)
總行數(shù):包括注釋以及空行在內(nèi)的代碼行數(shù);語(yǔ)句數(shù)目:有效的語(yǔ)句行數(shù),包括#include、#define、#undef 這三個(gè)預(yù)處理命令在內(nèi),括號(hào)不包含在內(nèi);分支語(yǔ)句比例:分支語(yǔ)句占總語(yǔ)句數(shù)目的比例;注釋比例:注釋占總行數(shù)的比例;函數(shù)數(shù)目:函數(shù)的數(shù)量;平均每個(gè)函數(shù)的語(yǔ)句數(shù);函數(shù)圈復(fù)雜度;函數(shù)最大嵌套層數(shù);類的數(shù)量;平均每個(gè)類的函數(shù)數(shù)量。2 基于的SourceMonitor代碼結(jié)構(gòu)檢查
當(dāng)前能夠進(jìn)行代碼結(jié)構(gòu)檢查的工具有不少,本文中選擇 SourceMonitor 作為代碼結(jié)構(gòu)檢查工具。
2.1 SourceMonitor簡(jiǎn)介
官網(wǎng)地址:https://www.derpaul.net/SourceMonitor/
SourceMonitor 是 Campwood Software LLC 擁有版權(quán)的自由軟件,非商業(yè)用途可免費(fèi)使用。
SourceMonitor的主要功能是對(duì)代碼的一個(gè)分析和度量。即使用SourceMonitor軟件我們可以清晰的看到代碼的總行數(shù),注釋比例,語(yǔ)句數(shù)以及類的個(gè)數(shù)和函數(shù)的個(gè)數(shù)。
SourceMonitor 有以下特點(diǎn):
支持對(duì) C、 C++、 C#、 VB.NET、 java、 Delphi、 Visual Basic以及 HTML 在內(nèi)的多種語(yǔ)言的源代碼的分析;效率高,每秒鐘能夠分析 10000 行以上的代碼;可以修改各個(gè)度量指標(biāo)的閾值。2.2 C語(yǔ)言度量值(C Metrics)
下面以C語(yǔ)言度量值為例,看看SourceMonitor都給我們反饋了哪些信息。
總行數(shù)(Lines):包括空行在內(nèi)的代碼行數(shù);
語(yǔ)句數(shù)目(Statements):在C語(yǔ)言中,語(yǔ)句是以分號(hào)結(jié)尾的。分支語(yǔ)句if,循環(huán)語(yǔ)句for、while,跳轉(zhuǎn)語(yǔ)句goto都被計(jì)算在內(nèi),預(yù)處理語(yǔ)句#include、#define和#undef也被計(jì)算在內(nèi),對(duì)其他的預(yù)處理語(yǔ)句則不作計(jì)算,在#else和#endif、#elif和#endif之間的語(yǔ)句將被忽略;
分支語(yǔ)句比例(Percent Branch Statements):該值表示分支語(yǔ)句占語(yǔ)句數(shù)目的比例,這里的“分支語(yǔ)句”指的是使程序不順序執(zhí)行的語(yǔ)句,包括if、else、for、while和switch;
注釋比例(Percent Lines with Comments):該值指示注釋行(包括/……/和//……形式的注釋)占總行數(shù)的比例;
函數(shù)數(shù)目(Functions):指示函數(shù)的數(shù)量;
平均每個(gè)函數(shù)包含的語(yǔ)句數(shù)目(Average Statements per Function):總的函數(shù)語(yǔ)句數(shù)目除以函數(shù)數(shù)目得到該值;
函數(shù)圈復(fù)雜度(Function Complexity):圈復(fù)雜度指示一個(gè)函數(shù)可執(zhí)行路徑的數(shù)目,以下語(yǔ)句為圈復(fù)雜度的值貢獻(xiàn)1:if/else/for/while語(yǔ)句,三元運(yùn)算符語(yǔ)句,if/for/while判斷條件中的"&&"或“||”,switch語(yǔ)句,后接break/goto/ return/throw/continue語(yǔ)句的case語(yǔ)句,catch/except語(yǔ)句;
函數(shù)深度(Block Depth):函數(shù)深度指示函數(shù)中分支嵌套的層數(shù)。
對(duì)其他語(yǔ)言,SourceMonitor輸出不同的度量值,例如在C++度量值中包括類的數(shù)目(Classes),在HTML中包括各個(gè)標(biāo)簽的數(shù)目(HTML Tags)、超鏈接數(shù)目(Hyperlinks)等。
2.2.1 SourceMonitor使用指南
首先在SourceMonitor官網(wǎng)下載SourceMonitor安裝包后,雙擊安裝包,按向?qū)нM(jìn)行安裝即可,這里就不再贅述了。
打開(kāi) SourceMonitor,選擇菜單“File→New Project”新建項(xiàng)目。
彈出如下圖所示的語(yǔ)言選擇對(duì)話框,選擇源文件的語(yǔ)言以及需要掃描的文件類型,SourceMonitor 對(duì)自動(dòng)掃描對(duì)應(yīng)的源文件進(jìn)行分析。 閏年判斷函數(shù)是使用 C 語(yǔ)言編寫(xiě)的, 所以選擇 C 語(yǔ)言,掃描的文件類型指定.c 和.h,然后點(diǎn)擊下一步繼續(xù)。
在接下來(lái)彈出的如下圖所示的對(duì)話框中,設(shè)置項(xiàng)目的名稱和保存路徑,并點(diǎn)擊下一步繼續(xù)。
在接下來(lái)彈出的如下圖所示的對(duì)話框中,填入源文件所在的目錄,并點(diǎn)擊下一步繼續(xù)。
設(shè)置源代碼目錄后,后面所有設(shè)置都采用默認(rèn)設(shè)置即可,一直點(diǎn)擊下一步直到完成。
在新建項(xiàng)目完成后,系統(tǒng)會(huì)自動(dòng)創(chuàng)建一個(gè)檢查點(diǎn),可以手動(dòng)修改檢查點(diǎn)的名稱和需要檢查的文件列表。修改完畢后,點(diǎn)擊OK 按鈕檢查點(diǎn)的創(chuàng)建,詳見(jiàn)下圖。
2.2.2 分析代碼結(jié)構(gòu)
新建項(xiàng)目并創(chuàng)建檢查點(diǎn)后,接下來(lái)就可以進(jìn)行代碼結(jié)構(gòu)分析了。在檢查列表中列出了當(dāng)前已經(jīng)創(chuàng)建的所有的檢查點(diǎn),詳見(jiàn)下圖。
針對(duì)每個(gè)檢查點(diǎn),SourceMonitor 給出了每個(gè)度量指標(biāo)的具體的值,可以通過(guò)左右劃動(dòng)滾動(dòng)條進(jìn)行查看。
如果需要查看某個(gè)檢查點(diǎn)是否有指標(biāo)超標(biāo),可右擊對(duì)應(yīng)的檢查點(diǎn),然后在右鍵菜單中選擇“Display CheckPoint Metrics Kiviat Graph”,詳見(jiàn)下圖。
打開(kāi)的指標(biāo)度量圖標(biāo)詳見(jiàn)下圖。
從指標(biāo)度量圖表中可以看出,每個(gè)指標(biāo)都有下限和上限值。 在實(shí)際應(yīng)用中,要求注釋比例和平均每個(gè)函數(shù)的代碼數(shù)必須在下限和上限指示的范圍內(nèi),而其他的指標(biāo)則要求不能超出上限,否則代碼就需要重構(gòu)。
若從指標(biāo)度量圖中發(fā)現(xiàn)某項(xiàng)指標(biāo)不合格,則可雙擊對(duì)應(yīng)的檢查點(diǎn)打開(kāi)文件列表。在打開(kāi)的文件列表中,可以通過(guò)點(diǎn)擊表頭改變排序方式以快速找到指標(biāo)不合格的文件。如下圖所示為按文件名升序進(jìn)行排序。
找到指標(biāo)不合格的文件,單擊鼠標(biāo)右鍵,然后在右鍵菜單中選擇“Display Function Metrics”打開(kāi)函數(shù)列表,詳見(jiàn)下圖。
同樣在打開(kāi)的函數(shù)列表中,可以通過(guò)點(diǎn)擊表頭改變排序方式以快速找到指標(biāo)不合格的函數(shù),然后就可以對(duì)對(duì)應(yīng)的函數(shù)進(jìn)行重構(gòu)。如下圖所示為按照函數(shù)名稱升進(jìn)行排序。
2.2.3 修改指標(biāo)閾值
在有些時(shí)候,開(kāi)發(fā)者可能并不希望使用系統(tǒng)默認(rèn)的指標(biāo)閾值,而是希望能夠自定義指標(biāo)閾值。 SourceMonitor 支持對(duì)各個(gè)指標(biāo)的閾值進(jìn)行自定義,這樣使用時(shí)就會(huì)更加靈活。選擇菜單“File→Option”,打開(kāi)選項(xiàng)設(shè)置對(duì)話框。
如果需要修改對(duì)應(yīng)語(yǔ)言的閾值,可以選中對(duì)應(yīng)的選項(xiàng)卡進(jìn)行修改即可。詳見(jiàn)下圖。