?

淺析代碼風格*

2013-07-31 08:27趙君喆鐘良驥盧社階戴文華
湖北科技學院學報 2013年4期
關鍵詞:閱讀者命名語句

趙君喆,鐘良驥,盧社階,聞 彬,戴文華

(湖北科技學院 計算機科學與技術學院,湖北 咸寧 437100)

代碼是程序員思維的體現,開發者如何通過代碼向維護者傳遞自己的思路和想法?這需要開發者盡可能地寫出讓大多數程序員都容易理解的代碼,也就是可讀性強的代碼。代碼的可讀性包括清晰的思路,流暢的邏輯以及規范的風格。采用公認的設計模式、流行的算法、常見的功能實現套路,避免“聰明”、“微妙”的技巧,都有助于體現代碼邏輯和思路,這些方面研究者甚多,本文不作深入討論。

代碼閱讀者對一個程序最直觀的感受是該程序的代碼風格(Coding Style)。代碼1是一段C語言程序,有過網絡編程經驗的開發者大概可以看出這是一個解析并處理網絡層數據包的函數。但是對一個沒有網絡編程經驗的開發者來說,這段代碼讓人感到驚慌。變量pp表示什么?常數14表示什么?沒有注釋,格式混亂,整段代碼無法理解。

相比代碼1,具有相同功能的代碼2則非常容易理解。從軟件工程學的角度出發,任何代碼應該可以讓任何專業人員來維護。因此,遵循良好的代碼風格,是軟件高效開發和維護的基礎。什么才是良好的代碼風格?行業并沒有嚴格的標準,但是大多數的軟件維護人員都希望開發人員能注意下面幾點。

一、規范地命名

變量、函數、類、源文件的名字會給代碼閱讀者帶來很多信息,包括正面的和負面的。良好的命名習慣,可以大大減少代碼維護者的閱讀開銷。規范地命名一般遵循以下原則:

1.為變量、函數、類和文件起一個有含義的名字。一個有具體含義的名字往往可以告訴人們這個對象是什么、起什么作用。

表1 命名對比

3.用詞性和大小寫來區分命名對象的種類。代碼的含義盡可能符合現實世界,所以名字的詞性也盡量符合命名對象的自然屬性。例如一般變量和類的名字采用名詞,函數的名字采用動詞。比如,class Duck{}、Duck greenDuck、greenDuck.Fly()。如例所示,有些名字是由幾個單詞組成,所以在名字中有的字母大寫,是為了界定單詞。有些程序員習慣將自定義的類名和函數名的首字母大寫,而變量的首字母小寫。其主要目的是為了將自定義的類及函數與系統和庫的類型及函數區分開。

4.名字攜帶更多信息。行內有些命名習慣讓名字攜帶更多的信息,如著名的“匈牙利命名法”。該命名法則在變量前面帶上類型或屬性信息,比如float型變量就以f為名字的開頭,指針變量就以為p為名字的開頭,成員變量以m_開頭,全局變量以 g_開頭等等。如:fRate、pWinHandle、m_color、g_nameMap等都是遵循匈牙利命名法的名字。

二、降低代碼噪聲

代碼反映出程序員的思維流,當代碼的維護者順著代碼的邏輯行云流水般地閱讀下來,他會覺得這段代碼就像一篇文章。事實上,有些代碼中存在著不少噪聲,這些噪聲往往會干擾甚至阻斷代碼閱讀者的思維。這些噪聲包括以下因素:

1.奇異數(Magic Number)。有些代碼中會出現突如其來的數字,這些數字又不帶任何字面的意思,所以當代碼維護者讀到這里的時候,往往會費盡心思來弄清楚這些數字代表著什么。代碼1中的14、6、17等數字就是奇異數,當它們被替換成代碼3中的ETHER_HEAD_LEN、PROTOCOL_TCP、PROTOCOL_UDP后,代碼的可讀性大大增強。所以定義有意義的宏常量是避免奇異數的好辦法。

2.多函數出口(Multiple Return)。函數作為一個功能性模塊體現出邏輯的封裝性,既然函數只有一個入口,那么最好只有一個出口。否則的話,代碼閱讀者還要額外考慮函數異常返回時的上下文安全情況,例如多個出口的函數在資源管理上就頗有不便:

在代碼3中,錯誤情況發生時忘記釋放資源就返回了,導致內存泄露。不過也可以在每個return前都寫上一段釋放資源的代碼避免內存泄露,但如果return過多,代碼不可避免的冗長重復,同樣降低了可讀性。因此可以修改為代碼4的形式,將函數設置唯一的出口,資源統一在出口前釋放,這樣的邏輯更加合理。

3.無條件跳轉。多年來大量的C開者證實,頻繁使用goto等一些無條件跳轉語句會導致程序邏輯混亂,很難維護。所以在軟件開發中,應該盡量避免goto、setjmp、longjmp等跳轉語句。

2)理論與實踐相結合,緊跟當前軟件技術發展的前沿,熟悉當前軟件項目開發流程和開發工具,強化編程能力,培養學生具有扎實的基礎理論知識和較強的工程項目應用能力、培養良好的職業素養和創新能力作為人才培養目標的重心,緊跟并培養以大數據為核心,移動互聯網等新一代信息技術產業所需的高級應用型軟件人才。

4.復雜的邏輯表達式。計算機解析處理大量的“與”、“或”、“非”等邏輯關系很容易,但人腦理解卻很難。例如,代碼5中的if條件理解起來需要花費很大的代價,但如果將邏輯表達式切分成多個if來處理,如代碼6,雖然代碼量略增,但可讀性更強。

三、合理的代碼格式

眾所周知,只要語法正確,再凌亂的格式也絲毫不妨礙編譯器對代碼的理解。但人卻不同,混亂不堪的格式總是讓代碼的閱讀者不知所措。井井有條的代碼格式不僅讓人看上去賞心悅目,更能節省代碼的閱讀時間。講究代碼格式實際上就是優化代碼的排版,程序開發者在長年累月的工作中積累了一些國際認可的代碼排版經驗。

1.縮進。子模塊通過縮進一個單位來體現代碼的邏輯層次,這個單位一般是4個空格。有些開發者習慣用tab縮進,但是不同的編輯器顯示tab的縮進大小不一定相同,層次結構分明的代碼在另一個編輯器里可能顯示的很混亂。所以一般建議在編輯器中設置:將tab替換成4個空格。

2.花括號?;ɡㄌ柕母袷街挥袃煞N習慣,各有優劣,但同一個工程中應該保持一致性。

3.對齊。每個程序塊的代碼都應該對齊,這樣能更清晰地體現出程序塊之間的邏輯層次。還有一些常見的對齊習慣,比如變量聲明定義對齊、參數對齊等,目的都是為了讓代碼看起來更清晰。

4.嵌套。大規模的嵌套條件語句會讓程序呈現階梯狀縮進形式,如代碼4里if語句嵌套if語句。這樣的代碼雖然有規范地縮進和對齊,但如果if語句很長,閱讀者將很難匹配花括號。所以這種情況可將代碼4改成代碼8。

四、有效的注釋

代碼注釋是代碼作者為代碼讀者提供的輔助信息,這些信息包括對功能的描述、對邏輯的解釋以及對易混淆處的提醒等等。

沒有注釋的代碼,即便是代碼作者,一個月后去閱讀,也會有很大的理解障礙。雖然書寫注釋是件乏味而麻煩的事情,但是對于代碼的維護者來說,好的注釋可以大幅提高代碼的閱讀速度。但是不合時宜或表達不清的注釋不但不能幫助代碼維護者閱讀代碼,有時還會干擾或誤導代碼的讀者。

書寫注釋一般應參考以下幾點:

1.注釋用語。好的注釋應當言簡意賅,條理清晰,不應將簡單的問題復雜化,亦不可將復雜的問題簡單化。此外,如果考慮產品市場的擴展性,注釋語言可以采用英語。

2.文件注釋。比較規范的文件注釋包括:工程信息、版權信息、版權許可信息、工程名、文件描述、作者、版本和修改歷史等。

3.類注釋。格式類似于文件注釋,但是注釋內容僅需包括:類名、類功能描述、類接口及使用說明。

4.函數注釋。格式類似于類注釋,內容包括 :函數名、函數功能、參數說明、返回值說明。

5.變量注釋。類的數據成員以及全局變量最好注明其含義和用途,這樣的注釋一般采用行注釋方式放在變量的上一行。

6.實現注釋。在代碼中一些機巧、晦澀、有趣、重要的地方應該加上實現注釋。如果是對程序塊注釋,一般采用行注釋塊注釋放在程序塊的上面;如果是對某語句注釋,一般采用行注釋緊鄰語句末尾。

7.提醒注釋。有時候程序員寫的一些看上去“不正?!钡拇a,需要提醒閱讀者這是有意為之。比如:未實現的功能需要注釋“TODO”,switch的case中有意不用break時需要注釋“Flow Down”。

五、結 語

歸根結底,無論采用什么樣的代碼風格,最重要的一點是要保持風格的一致性。一個工程,從開頭使用了一種風格,那么后面的所有代碼就應該延續之前的風格。遵循軟件工程學的思想,應參照以下幾個原則來保持代碼風格的一致性:

1.軟件開發商制訂內部統一的代碼風格框架,并對所有開發者進行代碼規范化培訓,從而保證企業內部代碼的易維護性。

2.項目啟動時制訂項目代碼風格細則,嚴格約束參與相同項目成員的代碼風格,以此保證項目整體的代碼風格一致性。

3.維護項目時,以被維護項目的代碼風格為標準,保證被維護項目的代碼風格的持續性。

猜你喜歡
閱讀者命名語句
閱讀者的春天
命名——助力有機化學的學習
“青春閱讀者”——教師讀書會紀實
重點:語句銜接
為什么有些人能成為終身閱讀者
閱讀者
有一種男人以“暖”命名
為一條河命名——在白河源
如何搞定語句銜接題
河鲀命名小考
91香蕉高清国产线观看免费-97夜夜澡人人爽人人喊a-99久久久无码国产精品9-国产亚洲日韩欧美综合