如何寫出讓自己滿意的代碼

轉(zhuǎn)自:http://kb.cnblogs.com/page/188214/

今天有位朋友在微博上問我這樣一個問題:

@老碼農(nóng)的自留地,最近出于學習目的寫一個管理系統(tǒng),越到后邊绳锅,越覺得自己前邊的代碼寫得爛。前輩陈症,我想讓代碼寫得更好一點叉寂,能不能談談你的經(jīng)驗,給我指點一下翁逞!”

我在回復里剛寫了幾句肋杖,就意識到140個字很難把我的想法說清楚,本著知無不言言無不盡的好為人師精神挖函,我決定把我的回答寫成一篇博文状植。

首先要說明的是,我寫這篇博客并不代表本人覺得自己的代碼寫得有多好怨喘。事實上我很清楚自己的水平津畸,作為一個做應用系統(tǒng)的程序員,和那些做框架做系統(tǒng)的大牛根本就不在一個層次必怜。而且即使在應用層次肉拓,我的水平大概也只能算二三流,只是因為熱愛編程所以一直在努力而已梳庆,但不管怎么說暖途,能做自己喜歡的工作我已經(jīng)很滿足了。所以我稍微篡改了一下問題膏执,針對“覺得自己前邊的代碼寫得爛”這個重點驻售,把這位朋友問的如何“讓代碼寫得更好一點”改成了“如何寫出讓自己滿意的代碼”

言歸正傳胧后,我自己的體會是寫代碼很像寫作文芋浮,開始寫之前的構(gòu)思過程是最關(guān)鍵的。記得高中的時候壳快,有位語文老師給我傳授的經(jīng)驗是纸巷,至少花三分之一的時間來構(gòu)思,反復斟酌中心思想眶痰、各個段落的大意瘤旨,文章的脈絡(luò),主要的修辭手法竖伯,等等存哲。把這些要素都想清楚了因宇,寫起來就可以一氣呵成。

我覺得寫代碼也是一樣祟偷,思路是最關(guān)鍵的察滑。假定采用的技術(shù)平臺、框架修肠、工具等已經(jīng)確定了贺辰,那么在開始動手寫之前,花三分之一以上的開發(fā)時間去把所有的數(shù)據(jù)結(jié)構(gòu)及其相互關(guān)系考慮清楚嵌施。例如需要定義幾個類饲化,類和類之間的關(guān)系是怎樣的,每個類里都有什么屬性吗伤,每個類提供一些什么樣的方法吃靠,等等,這些是最核心的足淆。這些數(shù)據(jù)結(jié)構(gòu)要考慮得盡可能細巢块,比如功能實現(xiàn)可能沒問題,但是性能上不理想缸浦,這就說明你的數(shù)據(jù)結(jié)構(gòu)設(shè)計還需要改進夕冲。這些細節(jié)要反復考慮,交叉檢驗裂逐,直到自己覺得很周到了為止。在此基礎(chǔ)上泣栈,再注意實現(xiàn)的細節(jié)卜高、測試用例、代碼可讀性南片,就應該可以寫出讓自己滿意的代碼掺涛。具體說明如下:

1. 數(shù)據(jù)結(jié)構(gòu)和核心算法

關(guān)于數(shù)據(jù)結(jié)構(gòu)的重要性,大神Linus Torvalds講過這樣的話疼进,我覺得非常贊同:”Bad programmers worry about the code. Good programmers worry about data structures and their relationships.” (低水平程序員總在考慮代碼薪缆,高水平程序員總在考慮數(shù)據(jù)結(jié)構(gòu)及其之間的關(guān)系)

數(shù)據(jù)結(jié)構(gòu)考慮清楚了,核心的算法自然就出來了伞广,這就是關(guān)于每個類的每個方法如何實現(xiàn)的問題拣帽。比如需要實現(xiàn)一個中位數(shù)查詢方法,如果你前面確定了數(shù)據(jù)保存的格式是一個列表嚼锄,那么你可以考慮采用插入排序法减拭;如果數(shù)據(jù)格式是自平衡二叉排序樹(AVL),則只需直接返回根節(jié)點就可以了区丑。

數(shù)據(jù)結(jié)構(gòu)決定算法拧粪,所以你在考慮數(shù)據(jù)結(jié)構(gòu)的時候修陡,一定要盡可能地使數(shù)據(jù)的結(jié)構(gòu)和它的自然屬性相匹配,不然后面的實現(xiàn)就會是一場噩夢可霎。比如魄鸦,你把一個多層級的結(jié)構(gòu)定義成二維數(shù)組,看上去也靠譜癣朗,相當于在一個表格里維護一個組織結(jié)構(gòu)圖拾因,可是當你做到部門增減的時候,本層級的數(shù)組元素移動自不必說斯棒,下面各個層級的元素移動就很容易亂套盾致,而且性能很差,可能你寫了2000行代碼還有很多邊界條件會出錯荣暮。相反庭惜,如果用一個孩子兄弟鏈表來表示這個樹型結(jié)構(gòu),操作起來就非常容易穗酥,可能100行都足夠了护赊。

2. 功能實現(xiàn)

思路確定后,實現(xiàn)過程也需要大量的構(gòu)思活動砾跃。碰到你比較熟悉有經(jīng)驗的領(lǐng)域骏啰,你自然可以輕車熟路,但難免會有一些你不太熟悉的技術(shù)需要嘗試抽高。有的同學比較排斥這種領(lǐng)域判耕,比如我好不容易才掌握了Struts 2,領(lǐng)導又讓我去學習Grails框架翘骂,我就會覺得很不爽壁熄,大概看了看就挑出它的一堆問題,然后能躲多遠就躲多遠碳竟〔萆ィ可是我要說,這樣的心態(tài)會阻礙自己不斷提高技術(shù)水平莹桅。作為一個程序員昌执,最大的挑戰(zhàn)也是最大的樂趣所在,就是不斷學習新的技術(shù)诈泼,沒有這樣的心態(tài)懂拾,很快就會落后。

好厂汗,那么遇到不熟悉的技術(shù)怎么辦委粉?我的體會是,先不要急著實現(xiàn)項目中的代碼娶桦,自己另外維護一個測試項目贾节,在里邊邊查文檔邊學習汁汗,邊做一個小功能,把所有需要在項目中實現(xiàn)的功能先在測試項目里跑通栗涂,然后再寫項目里的代碼知牌。這樣做的好處是把單個技術(shù)問題和其他潛在的bug隔離開來,便于快速學習新技術(shù)斤程。否則角寸,你直接在項目里寫代碼出錯以后,要判斷問題的源頭都要多費好幾倍的精力忿墅。

3. 測試

測試很重要扁藕,設(shè)計測試用例就像開發(fā)時設(shè)計數(shù)據(jù)結(jié)構(gòu)一樣,也是很關(guān)鍵的疚脐。在設(shè)計測試用例的時候亿柑,要把當時自己設(shè)計數(shù)據(jù)結(jié)構(gòu)的思路全部忘掉,或者找別人來設(shè)計測試用例棍弄,不然會不由自主地測試那些你已經(jīng)考慮到了的地方望薄。這樣測試是跑通了,用戶一用起來可能各種邊界條件會到處出問題呼畸。

有人會推崇TDD的方法痕支,先設(shè)計好測試用例,然后在開發(fā)過程中確保所有測試通過蛮原。我個人不喜歡這種方法卧须,雖然承認從開發(fā)質(zhì)量管理和長期維護的角度來說TDD是很有必要的,但我個人嘗試的結(jié)果是儒陨,設(shè)計完測試用例后故慈,想到開發(fā)的目標不是實現(xiàn)功能,而是為了跑通測試框全,就感到毫無樂趣可言。這一點我自己也覺得很矛盾干签。

寫到這里我又想到大神Linus說過的另一句話:”Regression testing” What’s that If it compiles, it is good; if it boots up, it is perfect. (“回歸測試”津辩?這是什么東西?如果代碼能編譯就是好的容劳,如果它啟動了喘沿,那就是完美的。)當然了竭贩,大神水平擺在那里蚜印,他有資本目空一切,咱確實沒資格仿效留量。但是我還是覺得TDD也有TDD的問題窄赋,測試是很重要哟冬,但把它擺到驅(qū)動開發(fā)的高度,就有點本末倒置了忆绰。這個是我自己的一點看法浩峡,本人對TDD了解得不深入,如果有謬誤之處错敢,請多多指教翰灾。

4. 代碼可讀性

要想自己滿意,代碼的可讀性一定要好稚茅。要做到一年后甚至幾年后你拿到自己寫的代碼纸淮,還能很容易看明白當時的思路和實現(xiàn)。這就涉及到命名和注釋的問題亚享。

命名就像超市里的商品標簽一樣咽块,要讓看得人一目了然就知道這是個什么東西,比如你的員工類里有兩個屬性分別是到崗日期和離職日期虹蒋,把它們定義成date1和date2就沒有多少可讀性糜芳,而定義成dateOnBoard和dateQuit就比較清晰。

注釋也是很重要的魄衅,它可以用來說明一段代碼的作用峭竣,算法的設(shè)計思想,或者是方法調(diào)用的參數(shù)格式要求等晃虫。有人覺得命名就是注釋皆撩,代碼本身就為自己代言了。我覺得這種說法用來強調(diào)命名規(guī)范的重要性是很好的哲银,但是因此說不需要注釋則有失偏頗扛吞。試想,如果Dijkstra首次發(fā)明最短路徑算法的時候荆责,他給出的代碼里沒有一行注釋滥比,即使所有的變量命名都定義得準確而嚴謹,又有幾個人能看懂他的算法呢做院?所以盲泛,在重要或者復雜的地方,都需要詳細地寫一些注釋键耕,便于看代碼的人清晰地了解你的思路寺滚。

最后總結(jié)一下:要想寫出自己滿意的代碼,首先不要急于動手屈雄,要先仔細想清楚思路性的東西村视,尤其是數(shù)據(jù)結(jié)構(gòu),然后在實現(xiàn)過程中大膽嘗試小心驗證酒奶,設(shè)計好測試用例蚁孔,確保代碼的可讀性奶赔,就可以在代碼中表現(xiàn)出自己的最高水平。但畢竟各人水平是有差異的勒虾,自己滿意并不等于其他人欣賞纺阔。我對此的看法是,不求盡如人意修然,但求無愧我心笛钝,足矣。最后再啰嗦一句愕宋,技術(shù)水平是可以慢慢提高的玻靡,但是好的編程習慣需要從一開始就養(yǎng)成,它會讓你在前進的道路上事半功倍中贝,受益終生囤捻。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市邻寿,隨后出現(xiàn)的幾起案子蝎土,更是在濱河造成了極大的恐慌,老刑警劉巖绣否,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件誊涯,死亡現(xiàn)場離奇詭異,居然都是意外死亡蒜撮,警方通過查閱死者的電腦和手機暴构,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來段磨,“玉大人取逾,你說我怎么就攤上這事∑恢В” “怎么了砾隅?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長债蜜。 經(jīng)常有香客問我琉用,道長,這世上最難降的妖魔是什么策幼? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮奴紧,結(jié)果婚禮上特姐,老公的妹妹穿的比我還像新娘。我一直安慰自己黍氮,他們只是感情好唐含,可當我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布浅浮。 她就那樣靜靜地躺著,像睡著了一般捷枯。 火紅的嫁衣襯著肌膚如雪滚秩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天淮捆,我揣著相機與錄音郁油,去河邊找鬼。 笑死攀痊,一個胖子當著我的面吹牛桐腌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播苟径,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼案站,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了棘街?” 一聲冷哼從身側(cè)響起蟆盐,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎遭殉,沒想到半個月后石挂,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡恩沽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年誊稚,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罗心。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡里伯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出渤闷,到底是詐尸還是另有隱情疾瓮,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布飒箭,位于F島的核電站狼电,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜澜术,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一纳决、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧削祈,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至吨拍,卻和暖如春褪猛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背羹饰。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工伊滋, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人严里。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓新啼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親刹碾。 傳聞我的和親對象是個殘疾皇子燥撞,可洞房花燭夜當晚...
    茶點故事閱讀 45,440評論 2 359

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