如何編寫(xiě)可讀性好的代碼

?

1.什么樣的代碼是可讀性好的代碼?

“讓人閱讀你的代碼戈钢,就像閱讀文章一樣流暢,就像閱讀散文詩(shī)一樣優(yōu)美是尔!”——這就是好代碼殉了!

把代碼當(dāng)作一篇優(yōu)美的散文詩(shī)來(lái)寫(xiě)!用這樣的標(biāo)準(zhǔn)來(lái)要求自己拟枚,一定會(huì)寫(xiě)出好代碼薪铜,一定會(huì)成為一個(gè)優(yōu)秀的程序員。

代碼不僅是寫(xiě)給機(jī)器編譯的恩溅,更是寫(xiě)給人看的隔箍!

代碼不僅是代碼,更是文檔脚乡!

2.理清思路再動(dòng)手——先寫(xiě)注釋鞍恢,再寫(xiě)代碼

清晰的思路是編程行動(dòng)的良好指南∶拷眩花點(diǎn)時(shí)間思考一下帮掉,不要一接到任務(wù)就動(dòng)手編代碼,從而陷入技術(shù)細(xì)節(jié)不可自拔窒典。

2.1 我的編程步驟

(1)在一個(gè)空的函數(shù)體內(nèi)用注釋寫(xiě)出自己的思路蟆炊,如:

  //功能說(shuō)明:XXX

  private void MyMainFunction()

  {

    //第1步,XXX

    //第2步瀑志,XXX

    MySubFunction ();//實(shí)現(xiàn)XXX

    //第3步涩搓,XXX

  }

  //功能說(shuō)明:XXX

  private void MySubFunction()

  {

    //先空著

    return 0;

  }

(2)理清思路后,在空白處填寫(xiě)自己的代碼劈猪。

如果某個(gè)步驟中實(shí)現(xiàn)起來(lái)感覺(jué)有點(diǎn)麻煩昧甘,那就先放一個(gè)空的子函數(shù),為這個(gè)子函數(shù)建一個(gè)空的函數(shù)體——保證編譯始終通過(guò)战得,稍后再填充這個(gè)空函數(shù)體充边。這種方法不影響你的整體思路,避免陷入編程細(xì)節(jié),同時(shí)又讓“大事化小浇冰,小事化了”贬媒。

(3)編完主函數(shù)后,填充空的子函數(shù)體肘习。

其實(shí)是對(duì)(1)(2)的迭代际乘。通過(guò)主函數(shù)的運(yùn)行效果,可以實(shí)時(shí)檢測(cè)子函數(shù)編寫(xiě)的正確與否漂佩。我們編寫(xiě)的子函數(shù)都即時(shí)被應(yīng)用場(chǎng)景所調(diào)用脖含,也就是即時(shí)的被測(cè)試,這不也是測(cè)試驅(qū)動(dòng)的思想嗎投蝉?事實(shí)證明器赞,這樣得到的函數(shù),比預(yù)先設(shè)計(jì)的函數(shù)更有用墓拜。

這樣港柜,只要思路清晰正確,編程就不會(huì)走太大彎路咳榜。

2.2 注釋?xiě)?yīng)先于代碼存在

注釋?xiě)?yīng)先于代碼存在夏醉,而不是編寫(xiě)完代碼之后去補(bǔ)注釋。因?yàn)槿斯逃械膽卸栌亢帉?xiě)完代碼之后都不情愿再去主動(dòng)加注釋畔柔,這使得代碼的可讀性變差。

另外臣樱,利用空白或空白行合理分隔代碼靶擦,也是一種良好的注釋。就像好的文章印刷雇毫,段落間距要大一點(diǎn)是一樣的玄捕。文章中也要留白!

C#代碼中可使用region合理分隔代碼棚放,同時(shí)在region中加入注釋枚粘。特別是,一定要把私有函數(shù)聚集到region中折疊起來(lái)飘蚯,不要與公有函數(shù)(或事件函數(shù))交叉馍迄,因?yàn)槲覀冮喿x代碼往往是從公有函數(shù)(或事件函數(shù))入手的。這可以隱藏細(xì)節(jié)局骤,使代碼看起來(lái)更整潔攀圈。

3.給變量起個(gè)好名字!

合理的變量命名是代碼可讀的基礎(chǔ)峦甩。好的命名赘来,不僅僅是使得代碼易讀,它代表了你對(duì)業(yè)務(wù)領(lǐng)域的理解,對(duì)程序邏輯的認(rèn)知撕捍,對(duì)項(xiàng)目框架的把握。所以泣洞,好的程序員很多時(shí)候糾結(jié)的不是技術(shù)實(shí)現(xiàn)問(wèn)題忧风,而是如何為變量起一個(gè)好名字,使得代碼讀起來(lái)流暢球凰,能讓更多的人理解狮腿!

遵循一些成熟的命名規(guī)范,給變量起個(gè)好名字的事會(huì)容易一些呕诉。接下來(lái)缘厢,我們探討一下常見(jiàn)的命名規(guī)范問(wèn)題。

(1)常見(jiàn)的大小寫(xiě)命名法

PascalCasing(大寫(xiě)開(kāi)頭):用于名字空間甩挫、類型贴硫、成員等的命名伊者,舉例:FileStream英遭。

camelCasing(駝峰命名法亦渗,小寫(xiě)開(kāi)頭):用于形參、局部變量法精、私有字段等的命名多律。舉例EncryptFile(string plainFile, string cypherFile)。

匈牙利命名法(小寫(xiě)開(kāi)頭狼荞,首單詞為數(shù)據(jù)類型):不推薦使用帮碰,因?yàn)镮DE的智能提示很容易讓你知道變量的類型粘秆。舉例:intCount、iCount收毫。(其實(shí)攻走,我們對(duì)匈牙利命名法有誤解此再,下篇再談)

另外,微軟建議不要在單詞間使用下劃線输拇。

(2)名字空間的命名

Company.Product.Subnamespace。舉例:

HuazemingTech.RailwayMis.Web

(3)類(結(jié)構(gòu))及對(duì)象的命名

名詞或名詞短語(yǔ)逛裤,因?yàn)樗鼈兇硐到y(tǒng)中的實(shí)體。舉例:

Student student;

List students;

(4)接口的命名

表示類型層次的根基時(shí):名詞或名詞短語(yǔ)带族,如:IList;

表示某種能力時(shí):形容詞或形容詞短語(yǔ)蝙砌,如IComparable择克。

(5)方法的命名

動(dòng)詞或動(dòng)詞短語(yǔ),DoSomething()肚邢。如:String.Split()

返回布爾值時(shí)使用表示肯定性的短語(yǔ),并考慮第三人稱缀旁。如:collection.Contains(item)

(6)屬性的命名

名詞短語(yǔ)或形容詞勺鸦。舉例:

public class ListView{

public ItemCollection Items {get;}//這里用復(fù)數(shù)形式

}

用肯定性短語(yǔ)命名布爾屬性,考慮前綴“Is/Can/Has”换途。舉例:CanRead、IsPostBack剃执。

(7)命名規(guī)范不是一成不變的

命名規(guī)范不是一成不變的懈息,在特定場(chǎng)景下可以有自己風(fēng)格的約定,前提是要使代碼保持一致辫继、易讀。比如遣耍,一般我們強(qiáng)烈反對(duì)使用漢語(yǔ)拼音命名變量炮车,可是在有些項(xiàng)目中酣溃,特別是涉及國(guó)內(nèi)政府纪隙、院校的信息標(biāo)準(zhǔn)時(shí),其數(shù)據(jù)庫(kù)字段(量很大)完全是按漢語(yǔ)拼音首字母制定的碘饼,如果非要翻譯成英文就有點(diǎn)矯枉過(guò)正了(工作量本身也很大)麸拄。一旦熟悉了這個(gè)行業(yè)之后黔姜,這些漢語(yǔ)拼音簡(jiǎn)寫(xiě)也就成了業(yè)務(wù)領(lǐng)域知識(shí)的一部分了,也就不那么別扭了秆吵,這也算中國(guó)特色吧。

4.如何檢測(cè)你的代碼是否規(guī)范主穗?

(1)人工檢測(cè):讓同伴閱讀你的代碼(結(jié)對(duì)編程毙芜,代碼復(fù)審),發(fā)現(xiàn)問(wèn)題晦雨。自我檢測(cè)隘冲,不懈追求――“讓人閱讀你的代碼,就像閱讀文章一樣流暢展辞!”。

(2)工具檢測(cè):FxCop洽腺,微軟的一個(gè)開(kāi)發(fā)工具覆旱,可以對(duì)編譯過(guò)的托管代碼進(jìn)行分析,并告訴用戶哪些地方不符合設(shè)計(jì)規(guī)范度液。(博友【金色海洋(jyk)陽(yáng)光男孩】推薦:R#--ReSharper: http://www.jetbrains.com/resharper/).

5.重構(gòu)你的代碼,做得更好一點(diǎn)點(diǎn)堕担!

嗅嗅代碼的壞味道:如果你發(fā)現(xiàn)在單頁(yè)中寫(xiě)了過(guò)多的MySubFunction,如果你檢測(cè)到不符合設(shè)計(jì)規(guī)范的代碼佑惠,如果你寫(xiě)了過(guò)長(zhǎng)的函數(shù)齐疙,如果你發(fā)現(xiàn)你在重復(fù)拷貝相同的代碼段……是時(shí)候重構(gòu)你的代碼了!

何謂重構(gòu)赌厅?重構(gòu)是對(duì)軟件內(nèi)部結(jié)構(gòu)的一種調(diào)整轿塔,目的是在不改變軟件可察行為的前提下,提高其可理解性勾缭,降低其修改成本。

為何重構(gòu)毒嫡?改進(jìn)軟件設(shè)計(jì)(消除重復(fù)幻梯,Don’t Repeat Yourself);使代碼更易理解(提高可讀性)膳叨;幫你找到Bug(Keep Your Code Clean)痘系;助你提高編程速度(后退是為了大踏步的前進(jìn))。

何時(shí)重構(gòu)汰翠?三次法則:事不過(guò)三,三則重構(gòu)健田。重構(gòu)不是重構(gòu)的目的佛纫,當(dāng)重構(gòu)能幫助你把后續(xù)的事情做得更好总放,那么還等什么好爬?重構(gòu)的時(shí)機(jī):添加功能時(shí),修補(bǔ)錯(cuò)誤時(shí)炬搭,復(fù)審代碼時(shí)穆桂。

如何重構(gòu)?小步前進(jìn)灼芭,不斷驗(yàn)證驼侠。(Done is Better Than Perfect)

常見(jiàn)的重構(gòu)原因和對(duì)策:

(1)代碼重復(fù)谆吴。提取為公共類/函數(shù)。

(2)代碼形式重復(fù)笋熬∧骞剑考慮模板類/泛型。

(3)過(guò)多函數(shù)的類筹吐。考慮使用partial分部類嘉竟,將類分拆到多個(gè)文件中去洋侨,每個(gè)分部類對(duì)應(yīng)一個(gè)文件。如MVC中Controller類往往會(huì)成為包含過(guò)多Action函數(shù)的類边苹,就可將其按功能域拆分為多個(gè)分部類裁僧。

(4)過(guò)長(zhǎng)的參數(shù)列表慕购。構(gòu)造一個(gè)對(duì)象茬底,包含所有要用的參數(shù)硝岗,然后將這個(gè)對(duì)象當(dāng)作參數(shù)即可移斩。

編程的過(guò)程實(shí)際是一個(gè)不斷重構(gòu)(改進(jìn))的過(guò)程赴魁。通過(guò)不斷重構(gòu)丹弱,可以去除代碼的壞味道谨胞,編寫(xiě)可讀性更好的代碼蒜鸡。同時(shí)也深化了你對(duì)設(shè)計(jì)的理解,提高了你的編程素養(yǎng)叶沛。

重構(gòu)忘朝,是一種生活態(tài)度,每天做得更好一點(diǎn)點(diǎn)溉箕。不要有過(guò)多的期望悦昵,一點(diǎn)點(diǎn)就好!不斷前進(jìn)但指,逐步逼近完美枚赡。

6.向微軟學(xué)習(xí),向MSDN學(xué)習(xí)贫橙!

微軟作為業(yè)界最為成功的軟件生產(chǎn)商,在各方面都有值得我們學(xué)習(xí)的地方疲迂。我覺(jué)得Windows、Office等是我們做界面和為用戶設(shè)計(jì)操作模式的最好老師郑气,當(dāng)我沒(méi)有思路的時(shí)候腰池,我都會(huì)打開(kāi)Windows的某個(gè)功能看看,就會(huì)受到啟發(fā)讳侨。

MSDN是我們學(xué)習(xí)編程的最好老師奏属。MSDN是眾多大師的智慧結(jié)晶。經(jīng)秤掠ぃ看MSDN中的類庫(kù)嘱腥,不僅可以系統(tǒng)的掌握類庫(kù)的功能,還可以學(xué)到如何給變量命名爹橱,如何進(jìn)行架構(gòu)設(shè)計(jì)等愧驱⊥终担看MSDN中的示例代碼,也是快速上手的捷徑掏颊;特別是一些“快速指南”乌叶,能很快讓你了解某個(gè)方面的開(kāi)發(fā)技術(shù)∽荚。總之乐横,看MSDN有百利而無(wú)一害今野,呵呵罐农,比看很多爛書(shū)強(qiáng)多了。(最近也發(fā)現(xiàn)了MSDN中一些代碼比較爛)

MSDN是幫助文檔涵亏,我們?cè)谑褂煤芏嘬浖龅絾?wèn)題時(shí)气筋,是否忽略了開(kāi)發(fā)者精心給我們準(zhǔn)備的幫助文檔呢?

(現(xiàn)在做APP裆悄,沒(méi)思路的時(shí)候就看看淘寶光稼、京東、微信艾君、支付寶冰垄,看他們的UI布局/設(shè)計(jì)、看他們的操作流程虹茶,能夠得到啟發(fā))

7.小結(jié)

通過(guò)注釋理清思路,給變量起好名字董济,重構(gòu)你的代碼要门,從MSDN中領(lǐng)悟大師真諦,其實(shí)都是一些編程習(xí)慣封豪,養(yǎng)成好的炒瘟、適合自己的習(xí)慣會(huì)受益終身。軟件大師Kent Beck說(shuō):

“我不是個(gè)偉大的程序員藻雌,我只是個(gè)有著一些優(yōu)秀習(xí)慣的程序員而已⊙倍牛”

——與諸君共勉做个!希望大家都成為具有優(yōu)秀習(xí)慣的程序員,編寫(xiě)散文詩(shī)一樣的代碼顽频!

參考文獻(xiàn)/推薦閱讀:

《編寫(xiě)可讀代碼的藝術(shù)》

《代碼整潔之道》

《.NET設(shè)計(jì)規(guī)范:約定太闺、慣用法與模式》

《重構(gòu)——改善既有代碼的設(shè)計(jì)》

備注:本文以C#編程為例,不足之處蟀淮,敬請(qǐng)批評(píng)指正钞澳。這是本人以前寫(xiě)的文章,第一次使用“簡(jiǎn)書(shū)”策治,試發(fā)一下兰吟,歡迎交流。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末讽膏,一起剝皮案震驚了整個(gè)濱河市拄丰,隨后出現(xiàn)的幾起案子料按,更是在濱河造成了極大的恐慌卓箫,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件闷盔,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡牡整,警方通過(guò)查閱死者的電腦和手機(jī)溺拱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)迫摔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人沪摄,你說(shuō)我怎么就攤上這事纱烘。” “怎么了凹炸?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵啤它,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我离赫,道長(zhǎng)塌碌,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任翎猛,我火速辦了婚禮切厘,結(jié)果婚禮上懊缺,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好舀凛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布猛遍。 她就那樣靜靜地躺著碎绎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪奸晴。 梳的紋絲不亂的頭發(fā)上日麸,一...
    開(kāi)封第一講書(shū)人閱讀 51,208評(píng)論 1 299
  • 那天代箭,我揣著相機(jī)與錄音,去河邊找鬼嗡综。 笑死,一個(gè)胖子當(dāng)著我的面吹牛察净,可吹牛的內(nèi)容都是我干的盼樟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼译秦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼筑悴!你這毒婦竟也來(lái)了延都?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎殊者,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體摔刁,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡海蔽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年党窜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片幌衣。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡豁护,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出断部,到底是詐尸還是另有隱情班缎,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布虱疏,位于F島的核電站苏携,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏装蓬。R本人自食惡果不足惜纱扭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一乳蛾、第九天 我趴在偏房一處隱蔽的房頂上張望鄙币。 院中可真熱鬧蹂随,春花似錦、人聲如沸绩衷。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)招盲。三九已至聪蘸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間控乾,已是汗流浹背娜遵。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工设拟, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人纳胧。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓跑慕,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親核行。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,082評(píng)論 25 707
  • 從百度文庫(kù)下載下來(lái)的惩系,這里保存一份 別人的原代碼程序員怎樣閱讀 源碼就是指編寫(xiě)的最原始程序的代碼如筛。 運(yùn)行的軟件是要...
    Albert陳凱閱讀 3,377評(píng)論 0 15
  • 累并快樂(lè)的一天赃承!今天有兩件重要事悴侵,一是我們一年級(jí)二班執(zhí)勤,主要在放學(xué)的時(shí)間攔截車(chē)輛禁止進(jìn)入抓于!二是小朋友們下午為迎十...
    Kitty粉樂(lè)樂(lè)閱讀 230評(píng)論 0 0
  • 唱一首歌 熟悉大段歌詞 卻忘記了名字 念一個(gè)人 記得好多細(xì)枝末節(jié) 卻只屬于回憶 你輕輕唱著的時(shí)候捉撮,可能某個(gè)人在聽(tīng) ...
    一窗秋陽(yáng)閱讀 95評(píng)論 0 0