編者按:原文轉(zhuǎn)載于2018年10月25日,閱讀量267?,F(xiàn)因內(nèi)容勘誤的目的,再次編輯。 手寫代碼時(shí),我們往往會(huì)遵照一些比較成熟的代碼指標(biāo)標(biāo)準(zhǔn)來約束代碼(比如:圈復(fù)雜度,參數(shù)個(gè)數(shù),嵌套層次等),以提高質(zhì)量(可參見本公眾號(hào)文章:談代碼指標(biāo))。在模型開發(fā)時(shí),是否有對(duì)應(yīng)的約束呢?分享一篇國內(nèi)模型開發(fā)大佬老胡的文章: 多年來,一直建議軟件開發(fā)的時(shí)候做到KISS(Keep It Simple, Stupid),但好像多數(shù)工程師對(duì)KISS沒啥興趣,經(jīng)常做出來非常復(fù)雜的模型,圈復(fù)雜度300多的模型我見過,圈復(fù)雜度600多的模型我也見過,圈復(fù)雜度800多的模型我還見過。這篇公眾號(hào)文章我有意選擇了一個(gè)或許能激發(fā)KISS愿望的圖片,期待能給大家?guī)硪稽c(diǎn)改變。 不得不說,ISO 26262的發(fā)布,讓越來越多的工程師開始關(guān)注模型的圈復(fù)雜度了,這是好事,利國利民的好事!ISO 26262中有關(guān)代碼和建模標(biāo)準(zhǔn)中有一條,叫做“Enforcement of low complexity”。正是這條規(guī)則讓汽車行業(yè)的模型開發(fā)工程師們開始關(guān)注圈復(fù)雜度這個(gè)指標(biāo)了。 于是,我們開始被問到: ——怎么計(jì)算模型的圈復(fù)雜度? ——模型的圈復(fù)雜度多大合適? ——如何降低模型的圈復(fù)雜度?等等。 好,下面我來大概說說這些問題。 圈復(fù)雜度的概念 圈復(fù)雜度用于衡量一個(gè)模塊判定結(jié)構(gòu)的復(fù)雜程度,數(shù)量上表現(xiàn)為獨(dú)立線性路徑的條數(shù)。圈復(fù)雜度的數(shù)據(jù)等于滿足判定全覆蓋所需要的測試用例的個(gè)數(shù)。 以上面這段控制流圖為例,有一種非常簡單的計(jì)算圈復(fù)雜度的方法,就是數(shù)出圖中節(jié)點(diǎn)間的連線把整個(gè)平面劃分為多少個(gè)區(qū)域,這段控制流圖我們數(shù)下來整個(gè)平面被分成了7個(gè)部分,那么它的圈復(fù)雜度就是7。 我們再看,如果我們在測試的時(shí)候,要做到判定全覆蓋,則需要如下測試用例: 1) N1-N2-N3-N6-N9 2) N1-N2-N5-N6-N9 3) N1-N2-N5-N8-N9 4) N1-N4-N5-N6-N9 或者N1-N4-N5-N8-N9 5) N1-N4-N8-N9 6) N1-N4-N7-N8-N9 7) N1-N7-N8-N9 注:假設(shè)1號(hào)節(jié)點(diǎn)用N1表示,2號(hào)節(jié)點(diǎn)用N2表示,….。 以上7個(gè)測試用例,可以滿足圈復(fù)雜度為7的模塊判定全覆蓋。 圈復(fù)雜度對(duì)開發(fā)活動(dòng)的影響 復(fù)雜度對(duì)于開發(fā)活動(dòng)的影響是多方面的,我試著來說一下看,有不完善的地方,也希望朋友們補(bǔ)充。 首先看可測性,圈復(fù)雜度提出的初衷主要是為了評(píng)價(jià)軟件的可測性。從上述圖例我們也可以看到,如果我們在測試過程中要求做到判定覆蓋率100%覆蓋,那么我們需要的測試用例個(gè)數(shù)就是圈復(fù)雜度的數(shù)值。如果圈復(fù)雜度過高,無疑會(huì)給單元測試帶來很大麻煩,且不說寫這么多測試用例本身就是一件非常繁雜的事情,這么多的測試用例對(duì)于后期的維護(hù)和管理也非常困難。 再看設(shè)計(jì)難度,高復(fù)雜度模塊的可設(shè)計(jì)性也會(huì)大打折扣,但有一點(diǎn),算法的不同描述方式,我們能夠應(yīng)對(duì)的復(fù)雜程度應(yīng)該是不同的。比如,同樣是復(fù)雜度為50的模塊,如果分別使用匯編語言、C語言、圖形化語言來描述,開發(fā)難度可想而知。圖形化設(shè)計(jì)可以應(yīng)對(duì)更高的復(fù)雜度,但不是說可以無限制的提高復(fù)雜度,至于什么樣的復(fù)雜度合適,我認(rèn)為這是一個(gè)經(jīng)驗(yàn)值,適合你開發(fā)團(tuán)隊(duì)的才是最好的。需要強(qiáng)調(diào)一點(diǎn),選擇不同的描述形式,對(duì)于模塊單元測試的可測性沒有改變。 再就是高復(fù)雜度對(duì)于可維護(hù)性的影響,我們開發(fā)產(chǎn)品,不可能做到“一次發(fā)布再無變更”,更多情況下,我們會(huì)面臨非常頻繁的變更,過于復(fù)雜的模型,我們很難應(yīng)對(duì)各種變更,“牽一發(fā)而動(dòng)全身”的尷尬可能很多人已經(jīng)深有體會(huì)。 高復(fù)雜度的這些害處不難理解,如何降低復(fù)雜度這是越來越多的開發(fā)者正在關(guān)心的問題,降低復(fù)雜系統(tǒng)的復(fù)雜度沒有捷徑,模塊化,將復(fù)雜的系統(tǒng)分解為若干個(gè)模塊,保證分解后的模塊都不復(fù)雜即可,而模塊化的原則我們都非常熟悉:高內(nèi)聚、低耦合。 方法和原則非常簡單,但實(shí)施這個(gè)過程卻并不簡單,這需要基于足夠深入的需求分析,這需要足夠長的時(shí)間去完成,而目前很多公司的開發(fā)過程中,需求分析過程花費(fèi)的時(shí)間實(shí)在太少。沒有足夠深入的需求分析,就難以對(duì)復(fù)雜系統(tǒng)做出合理的劃分,后續(xù)的工作只會(huì)越來越麻煩,甚至有公司因?yàn)槟P瓦^于復(fù)雜而被迫重新設(shè)計(jì)。 如何計(jì)算Simulink模型的圈復(fù)雜度 Simulink Check提供了對(duì)模型圈復(fù)雜度的計(jì)算功能,打開Simulink模型的Analysis菜單,然后選中Model Advisor,然后繼續(xù)打開ByTask>Model Metrics>Cyclomatic Complexity 然后點(diǎn)擊右側(cè)面板的Run This Check即可得到模型以及各個(gè)子系統(tǒng)的圈復(fù)雜度。 還有一個(gè)問題需要強(qiáng)調(diào):我們只關(guān)注單元模塊的圈復(fù)雜度,我們也只能做到單元模塊低復(fù)雜度設(shè)計(jì),我們不能要求整個(gè)系統(tǒng)不復(fù)雜,是吧?! |
|