咨詢電話:023-6276-4481
熱門文章
電 話:023-6276-4481
郵箱:broiling@qq.com
地址:重慶市南岸區(qū)亞太商谷6幢25-2
作為軟件開發(fā)者,我們可以開發(fā)低等級(jí)的軟件,但不能開發(fā)低質(zhì)量的軟件。所以,如何實(shí)施質(zhì)量保證,是我們關(guān)注的主要問題之一,而編碼規(guī)范則是實(shí)施質(zhì)量保證的第一步。
編碼規(guī)范已經(jīng)成為一個(gè)老生常談的問題,幾乎每個(gè)項(xiàng)目,每家公司都會(huì)定義自己的編碼規(guī)范。但在真正實(shí)施時(shí),卻在有意或無(wú)意地違背編碼規(guī)范。程序員,不喜歡改變自己的編程習(xí)慣。加之,管理者對(duì)質(zhì)量控制不足,導(dǎo)致編碼規(guī)范往往形同虛設(shè)。有些人會(huì)認(rèn)為:遵守編碼規(guī)范不能給項(xiàng)目帶來(lái)利益,也不能讓客戶看到我們?yōu)榇烁冻龅呐?,其完全是團(tuán)隊(duì)自發(fā)的行為,沒有必要做硬性的要求。還有些人有更好的理由:編碼規(guī)范會(huì)破壞創(chuàng)造性和程序質(zhì)量。我認(rèn)為,編碼規(guī)范,在軟件構(gòu)件以及項(xiàng)目管理中,甚至是個(gè)人成長(zhǎng)方面,都發(fā)揮著重要的作用,好的編碼規(guī)范是提高我們代碼質(zhì)量的最有效的工具之一。
提高可讀性 “任何一個(gè)傻瓜都能寫出計(jì)算機(jī)可以理解的代碼,唯有寫出人類容易理解的代碼,才是優(yōu)先的程序員?!本幋a規(guī)范,幫助我們寫出人類容易理解的代碼,它為我們提供了最基本的模板,良好的編碼風(fēng)格,使代碼具有一定的描述性,可以通過名字來(lái)獲取一些需要IDE才能得到的提示,如可訪問性、繼承基類等。
統(tǒng)一全局,促進(jìn)團(tuán)隊(duì)協(xié)作 開發(fā)軟件是一個(gè)團(tuán)隊(duì)活動(dòng),而不是個(gè)人的英雄主義。編碼規(guī)范,要求團(tuán)隊(duì)成員遵守這一統(tǒng)一的全局決策,這樣成員之間可以輕松地閱讀對(duì)方的代碼,所有成員正以一種清晰而一致的風(fēng)格進(jìn)行編碼。而且,開發(fā)人員也可以集中精力關(guān)注他們真正應(yīng)該關(guān)注的問題——自身代碼的業(yè)務(wù)邏輯,與需求的契合度等局部問題。
有助于知識(shí)傳遞,加快工作交接 風(fēng)格的相似性,能讓開發(fā)人員更迅速,更容易理解一些陌生的代碼,更快速地理解別人的代碼。因?yàn)?,他和你的代碼風(fēng)格是一樣的,你沒有必要對(duì)他的一些個(gè)性化風(fēng)格進(jìn)行揣測(cè)。這樣的好處是開發(fā)人員可以很快的接手項(xiàng)目組其他成員的工作,快速完成工作交接。
減少名字增生,降低維護(hù)成本 在沒有規(guī)范的情況下,和容易為同一類型的實(shí)例起不同的名字。對(duì)于以后維護(hù)這些代碼程序員來(lái)說(shuō)會(huì)產(chǎn)生疑惑。
強(qiáng)調(diào)變量之間的關(guān)系,降低缺陷引人的機(jī)會(huì) 命名可以表示一定的邏輯關(guān)系,是開發(fā)人員在使用時(shí)保持警惕,從而一定程度上減少缺陷被引人的機(jī)會(huì)。
提高程序員的個(gè)人能力 不可否認(rèn),每個(gè)程序員都應(yīng)該養(yǎng)成良好的編碼習(xí)慣,而編碼規(guī)范無(wú)疑是教材之一。從一個(gè)程序員的代碼本身能看出很多東西。所以,即便是為了自身發(fā)展,作為程序員也沒有理由抵制這種規(guī)則的存在。你可能沒有認(rèn)識(shí)到,我們正默默地得益于編碼規(guī)范。
在高質(zhì)量的軟件中,你可以看到“架構(gòu)的概念完整性”與“底層實(shí)現(xiàn)”之間的關(guān)系?!皩?shí)現(xiàn)”與“架構(gòu)”必須是清晰一致的,這種內(nèi)在的、固有的一致性,需要編碼規(guī)范來(lái)維系。如果沒有這種統(tǒng)一的約定,那么我們做出的東西可能會(huì)充斥著各種不同的風(fēng)格,顯得混亂且難以理解。團(tuán)隊(duì)成員之間可能很不理解彼此之間的想法,甚至是相互抨擊。各種編碼風(fēng)格上的差異會(huì)不斷擴(kuò)大,而代碼質(zhì)量則不斷下降。而且,團(tuán)隊(duì)成員會(huì)花費(fèi)時(shí)間在理解不同編程風(fēng)格之間的差異,而沒有專注于真正應(yīng)該解決的問題。這樣的時(shí)間消耗是難以接受的。所以,在每一個(gè)高質(zhì)量代碼的背后,一定存在著一份優(yōu)秀的編碼規(guī)范。
然而,也必須認(rèn)識(shí)到編碼規(guī)范不是“物神”。編碼規(guī)范僅僅是一個(gè)全局性質(zhì)的規(guī)范,它只不過是一種編程約定,不能解決更深層次的問題。就像一篇格式漂亮但內(nèi)容糟糕的論文不能被發(fā)表一樣,你不能僅靠一個(gè)規(guī)范來(lái)擺脫軟件作坊。而且,在編碼規(guī)范中不宜包含那些冗長(zhǎng)的開發(fā)技巧。我認(rèn)為,對(duì)于代碼是最佳實(shí)踐應(yīng)該是代碼審查所要解決的,應(yīng)該避免將編碼規(guī)范寫成一部關(guān)于重構(gòu)的教科書。
以下是我對(duì)定義編碼規(guī)范的一些建議:
求同存異 不要妄圖改變組織的編碼習(xí)慣,除非有絕對(duì)合理的理由,否則還是以民主為主,畢竟你沒有權(quán)利要求所有人都沿用你的編碼習(xí)慣。
定義編碼規(guī)范越早越好 也早使用編碼規(guī)范,也早享受其帶來(lái)的好處。
將規(guī)范分為強(qiáng)制部分和推薦部分 求同存異的具體實(shí)現(xiàn)。將最基本的規(guī)范列放在強(qiáng)制部分,所有成員必須遵守;將好的但不重要的習(xí)慣列在推薦部分,開發(fā)人員可以根據(jù)自己習(xí)慣選擇是否使用。
編碼規(guī)范不要太長(zhǎng) 太長(zhǎng)的文檔沒人看,所有人都一樣,除了禮品單和工資單沒人愿意看長(zhǎng)的東西,所以編碼規(guī)范必須精煉,最好是只有2~3頁(yè),讓開發(fā)人員可以打印出來(lái)隨時(shí)查看。
必須是約定俗成的 規(guī)范必須是行業(yè)中約定俗成的,不要有什么個(gè)性化發(fā)揮。
我本人不太推薦制定過細(xì)的編碼規(guī)范。制定編碼規(guī)范是為了增強(qiáng)代碼的可讀性,畢竟代碼的結(jié)構(gòu)才是主要關(guān)注問題,所以我的編碼規(guī)范還是比較簡(jiǎn)短的。里面只是對(duì)可能會(huì)破壞編碼風(fēng)格的行為進(jìn)行約束,而沒有細(xì)化到“空行”甚至“空格”的級(jí)別。
一 命名空間
<公司名稱>.(<產(chǎn)品名稱>|<相關(guān)技術(shù)>)[.<用途>] [.<子命名空間>]
二 代碼風(fēng)格
花括號(hào)“{}”不允許省略,即使只有一段代碼。
不允許省略訪問修飾符。
類型默認(rèn)是密封的。
不允許公開字段。
使用括號(hào)“()”來(lái)強(qiáng)調(diào)運(yùn)算符優(yōu)先級(jí)。
三 命名規(guī)范
(一) 類、結(jié)構(gòu)和接口的命名
使用名詞或名詞短語(yǔ)。
使用Pascal方式。
在接口名稱前加上前綴“I”。
考慮在派生類末尾使用基類的名字。
如果該類僅僅為了實(shí)現(xiàn)某個(gè)接口,那么請(qǐng)保持其與接口命名的統(tǒng)一。
如果從.NET 框架中存在的類型派生的類型,應(yīng)該遵循以下規(guī)范:
基類 | 派生類 |
System.Attribute | 要給自定義的特性添加“Attribute”后綴 |
System.Delegate | 要給用于事件處理的委托添加“EventHandler”后綴 要給用于事件處理之外的那些委托添加“Callback”后綴 不要給委托添加“Delegate”后綴 |
System.EventArgs | 要添加“EventArgs”后綴 |
System.Exception | 要添加“Exception”后綴 |
IDictionary,IDictionary<T,V> | 要添加“Dictionary”后綴 |
IEnumerable,ICollection,IList, IEnumerable,ICollection,IList | 添加“Collection”后綴 |
System.IO.Stream | 添加“Stream”后綴 |
CodeAccessPermission,IPermission | 添加“Permission”后綴 |
(二) 成員的命名
成員 | 大小寫 | 規(guī)范 |
方法 | Pascal(公開)、Camel(私有) | 用動(dòng)詞或動(dòng)詞短語(yǔ)命名 |
屬性 | Pascal | 用名詞、名詞短語(yǔ)或形容詞來(lái)命名 集合屬性應(yīng)該使用復(fù)數(shù)形式,而不是添加后綴 用“Is”、“Can”、“Has”等表示布爾屬性 可以用屬性的類型名來(lái)命名屬性 |
事件 | Pascal | 使用動(dòng)詞或動(dòng)詞短語(yǔ)來(lái)命名事件 用現(xiàn)在時(shí)和過去時(shí)來(lái)區(qū)分前置和后置事件 |
字段 | Camel(私有) | 要用名詞、名詞短語(yǔ)或形容詞來(lái)命名 不要加任何前綴 |
(三) 參數(shù)的命名
Camel風(fēng)格。
要使用left和right來(lái)命名重載的二元操作符的參數(shù)——如果參數(shù)沒有具體的含義。
要使用value來(lái)命名重載的一元操作符的參數(shù)——如果參數(shù)沒有具體的含義。
不要在參數(shù)中使用數(shù)字編號(hào)。
盡量使用描述性的名字命名泛型類型參數(shù),并在前面使用“T”前綴。
(四) 常量、變量的命名
常量——所有單詞大寫并用“_”分隔。
局部變量——Camel風(fēng)格。
(五) 枚舉的命名
Pascal風(fēng)格。
使用名詞的復(fù)數(shù)形式來(lái)命名標(biāo)記枚舉。
不要添加“Enum”或“Flag”后綴。
不要給枚舉類型值的名字加前綴。
(六) 資源的命名
Pascal風(fēng)格。
僅使用字母、數(shù)字和下劃線。
在命名異常消息的資源時(shí),資源標(biāo)識(shí)符應(yīng)該是異常類型名加上簡(jiǎn)短的異常標(biāo)識(shí)符。
(七) 數(shù)據(jù)庫(kù)命名
表——“模塊名_表名”。
字段——bool類型用“Is”、“Can”、“Has”等表示;日期類型命名必須包含“Date”;時(shí)間類型必須包含“Time”。
存儲(chǔ)過程——使用“proc_”前綴。
視圖——使用“view_”前綴。
觸發(fā)器——使用“trig_”前綴。
(八) XML命名
節(jié)點(diǎn)名稱使用Pascal風(fēng)格,屬性名稱使用Camel風(fēng)格。
四 注釋
對(duì)接口和復(fù)雜代碼塊必須進(jìn)行注釋。
修改代碼時(shí)保持注釋同步。
未完成的功能使用TODO標(biāo)記。
修改他人代碼時(shí)要先注釋對(duì)方代碼,并寫明修改原因,不允許隨便刪除他人代碼。
發(fā)布前移除無(wú)用注釋。
五 異常處理
原則上只允許顯示拋出InvalidOperationException、ArgumentException、ArgumentNullException和ArgumentOutOfRangeException四種異常類型。
在自定義異常時(shí),必須使用VS提供的代碼模板來(lái)創(chuàng)建自定義異常。