如何編寫更棒的代碼:11個(gè)核心要點(diǎn)
為一個(gè)合格的程序員,有太多的理由促使你去編寫干凈利落且可讀性強(qiáng)的代碼。最重要的是因?yàn)槟憔帉懙拇a,將來(lái)會(huì)有很多人一次次地閱讀。當(dāng)你有一天回過(guò)頭來(lái)看自己的代碼時(shí),你就會(huì)明白編寫優(yōu)雅的代碼是多么的重要。另外,如果別人來(lái)閱讀你編寫的代碼,你是否想知道別人看到那些爛代碼無(wú)比抓狂的感受。因此,花多一點(diǎn)的時(shí)間去編寫優(yōu)雅的代碼,將來(lái)說(shuō)不定會(huì)給你節(jié)省更多的時(shí)間。
那么,如何編寫更棒的代碼,下面是11條基本規(guī)則:
1、保持方法簡(jiǎn)短扼要
2、永遠(yuǎn)永遠(yuǎn)不要將同一個(gè)變量用于不同的目的
3、盡可能讓變量和方法的名稱能夠描述要實(shí)現(xiàn)的功能
4、盡可能將變量定義在最靠近它們的地方
5、不要出現(xiàn)讓人費(fèi)解的數(shù)字
6、要像對(duì)待朋友一樣對(duì)待你擅長(zhǎng)的語(yǔ)言
7、不要逆常規(guī)而行
8、千萬(wàn)小心過(guò)早的優(yōu)化代碼
9、要常常重構(gòu)經(jīng)過(guò)測(cè)試的代碼
10、不要沉溺于過(guò)度的設(shè)計(jì)技巧
11、隨時(shí)隨地學(xué)習(xí)新的知識(shí)
下面我們來(lái)對(duì)每一點(diǎn)詳細(xì)展開介紹。
1、保持方法簡(jiǎn)短扼要
盡管很多人都遵循這條規(guī)則,但是它依然很重要。總的來(lái)說(shuō),編寫的方法***能在首屏完全顯示。試想,如果你需要滾動(dòng)頁(yè)面才能看到整一個(gè)方法,那是一件多么分散注意力的事情。一個(gè)方法***能保持在5 – 20行之間,當(dāng)然,你也要視具體情況而定,并不是一概而論的。對(duì)于getter和setter方法,通常只需一行代碼,所以它們看起來(lái)更像是類成員的存取訪問(wèn)器。
2、遠(yuǎn)永遠(yuǎn)不要將同一個(gè)變量用于不同的目的
一個(gè)變量應(yīng)該只能被用于一個(gè)目的,我們可以通過(guò)使用常量(C++中用const標(biāo)識(shí),Java中用final標(biāo)識(shí)),幫助編譯器優(yōu)化代碼編譯,也可以向程序標(biāo)識(shí)“這個(gè)變量是不能被改變的”,這樣我們編寫的代碼就有更好的可讀性。
3、盡可能讓變量和方法的名稱能夠描述要實(shí)現(xiàn)的功能
一段通俗易懂的程序代碼,應(yīng)該是任何人只要看了代碼,就能明白程序是用來(lái)干嘛的。所以我建議大家盡量少用縮寫,除非是程序界公認(rèn)的簡(jiǎn)寫習(xí)慣,像下面的簡(jiǎn)寫習(xí)慣:
- src - source pos - position prev - previous
如果你覺得描述性的簡(jiǎn)寫方式?jīng)]有價(jià)值,你可以比較一下n, ns, nsisd和numTeamMembers, seatCount, numSeatsInStadium。
4、盡可能將變量定義在最靠近它們的地方
當(dāng)你在蓋房子的時(shí)候,總不希望把錘子放在別人家的院子里吧,相反,你會(huì)把蓋房的工具放得盡可能近,定義變量也是同樣的道理。
- int foo = 3; int bar = 5; // bunch of code that uses "bar" // but doesn't care about "foo" // ... baz(foo);
我們可以這樣重構(gòu)代碼:
- int bar = 5; // bunch of code that use "bar" // but doesn't care about "foo" // ... int foo = 3; baz(foo);
當(dāng)你把變量的聲明跟使用它的地方相隔太遠(yuǎn)的時(shí)候(甚至是超過(guò)一屏),那的確會(huì)給你帶來(lái)很大的麻煩。你會(huì)經(jīng)常滾動(dòng)頁(yè)面去尋找這個(gè)變量,導(dǎo)致你很難在大腦中保持代碼之間的連貫性。
5、不要出現(xiàn)讓人費(fèi)解的數(shù)字
任何時(shí)候,你要比較一些常量時(shí),都要將它們定義成constant類型。團(tuán)隊(duì)之間調(diào)試代碼時(shí)最讓人頭疼是出現(xiàn)下面的代碼:
- il < 4384
把它替換成下面的代碼該多好:
- inputLength < MAX_INPUT_LENGTH
6、要像對(duì)待朋友一樣對(duì)待你擅長(zhǎng)的語(yǔ)言
學(xué)習(xí)一種新的編程語(yǔ)言是一件很有趣的事情,從中你可以用很酷的方式學(xué)到新東西。還有就是讓一個(gè)對(duì)某種語(yǔ)言很專業(yè)的人去學(xué)另外一種語(yǔ)言,很多時(shí)候會(huì)讓人心有余而力不足。舉個(gè)例子,你讓一個(gè)Java大牛去學(xué)Ruby,他應(yīng)該會(huì)用Ruby的方式去解決問(wèn)題,而不是繼續(xù)沿用Java的解決問(wèn)題的思想。
當(dāng)你需要循環(huán)輸出5遍”Hello World“時(shí),Java代碼應(yīng)該會(huì)是這樣:
- for (int i = 0; i < 5; i++) { System.out.println("Hello world!"); }
但是用Ruby,你也許會(huì)這樣寫:
- for i in (0..5) puts "Hello world!" end
這些看上去都很不錯(cuò),但是最***的方式可能是下面這樣:
- 5.times { puts "Hello world!" }
7、不要逆常規(guī)而行
每一種編程語(yǔ)言都有自己的約束習(xí)慣,總的來(lái)說(shuō),大家對(duì)Java的編程習(xí)慣可能會(huì)了解得比較多,我們一起來(lái)看看其中的一些習(xí)慣:
方法名以小寫字母開頭,后面緊跟的是大寫字母開頭的單詞,比如veryLongVariableName。
類名一般都是大寫字母開頭的單詞組合。
常量的命名都是大寫字母的單詞,之間用下劃線隔開,比如MY_CONSTANT
左大括號(hào)應(yīng)該跟if在同一行
只有在迫不得已的時(shí)候才能打破這種規(guī)則,千萬(wàn)不要因?yàn)椴幌矚g這種做法而違背已經(jīng)約定好的編碼習(xí)俗。如果你身為團(tuán)隊(duì)一員,想改變一些編碼規(guī)則的話,那也可以,不過(guò)當(dāng)你把自己的代碼分享給沒有你這種習(xí)慣的隊(duì)友的時(shí)候,棘手的問(wèn)題會(huì)迎面而來(lái)。
8、千萬(wàn)小心過(guò)早的優(yōu)化代碼
過(guò)早的優(yōu)化是所有問(wèn)題的根源,至少電視上是這么說(shuō)的…你的首要任務(wù)是編寫容易理解的代碼,而不要求你能很快寫出來(lái)。除非你的程序運(yùn)行很慢,否則談優(yōu)化都是為時(shí)太早。如果你想優(yōu)化你的程序,那么得先找出程序的問(wèn)題,這就是我們需要profilers這個(gè)工具的原因。
在沒有找到問(wèn)題源頭就去優(yōu)化代碼,這樣做你所要付出的代價(jià)就是破壞了程序的結(jié)構(gòu),至少會(huì)喪失程序的可讀性。如果你發(fā)現(xiàn)程序運(yùn)行緩慢了,也不要盲目地重構(gòu)代碼,要先找到導(dǎo)致運(yùn)行慢的根本原因。
千萬(wàn)不要傻乎乎地去解決根本不存在的問(wèn)題。
9、要常常重構(gòu)經(jīng)過(guò)測(cè)試的代碼
世上沒有絕對(duì)***的事情。盡管你認(rèn)為自己的代碼已經(jīng)寫得非常***了,過(guò)一段時(shí)間也要經(jīng)常去看看它,也許那時(shí)你會(huì)對(duì)自己大罵:”怎么會(huì)那么傻!”
有一種提高代碼質(zhì)量的方法,那就是經(jīng)常重構(gòu)通過(guò)測(cè)試的代碼。所謂通過(guò)測(cè)試,我指的是程序要能正常工作,你可以通過(guò)自動(dòng)化測(cè)試或者手動(dòng)測(cè)試來(lái)確保這一點(diǎn)。
首先你要確保程序能夠正常運(yùn)行,***次我們并不需要寫出多么***的程序,能用就行,接下來(lái)我們可以慢慢重構(gòu),讓它逐漸變得***。這種開發(fā)方式很有TDD的味道,關(guān)鍵在于你需要熟悉重構(gòu)的每一個(gè)環(huán)節(jié)。如果你熟練使用一些高級(jí)的IDE,像IntelliJ IDEA,那你的重構(gòu)工作將會(huì)簡(jiǎn)單很多。
重構(gòu)完以后,也許你會(huì)碰到很多這樣那樣的問(wèn)題,甚至?xí)茐恼5某绦颍@就是我們要利用自動(dòng)化測(cè)試的原因了。當(dāng)你重構(gòu)完以后,跑一遍單元測(cè)試就能避免這些令人頭疼的問(wèn)題了。
10、不要沉溺于過(guò)度的設(shè)計(jì)技巧
當(dāng)我***次接觸到設(shè)計(jì)模式這一概念時(shí),我覺得自己找到了“圣杯”。這些精妙的設(shè)計(jì)思想可以讓你工作更加順利,也可以讓你的設(shè)計(jì)淺顯易懂,因?yàn)槟憧梢院?jiǎn)單的說(shuō)“我使用了觀察者模式”,而不同大費(fèi)周章的解釋一通。然而問(wèn)題來(lái)了,由于有些問(wèn)題看起來(lái)太自然太簡(jiǎn)單了,你會(huì)把那些設(shè)計(jì)模式的思想應(yīng)用到任何地方,為什么不把這個(gè)類設(shè)計(jì)成單例模式(singleton)?干嘛不去創(chuàng)建一些工廠類呢?
于是用80行代碼就能完成的腳本,結(jié)果你用了10個(gè)類,15個(gè)接口和一堆泛型和注釋,這其中的97%代碼并沒有做實(shí)質(zhì)上的事情。設(shè)計(jì)模式雖然非常有用,可以幫助你簡(jiǎn)化設(shè)計(jì),但是這并不是說(shuō)你可以到處使用它們。你可以使用設(shè)計(jì)模式,但是不能將它濫用了。
11、隨時(shí)隨地學(xué)習(xí)新的知識(shí)
編程就是一項(xiàng)隨時(shí)學(xué)習(xí)新事物的工作,當(dāng)你學(xué)到了新的類庫(kù)或者編程語(yǔ)言時(shí),你會(huì)迫不及待地丟掉老的代碼,進(jìn)而去重寫它們。然而有很多理由說(shuō)明你不該這么做。
將一個(gè)新的類庫(kù)或者框架應(yīng)用到現(xiàn)有的項(xiàng)目中就會(huì)出現(xiàn)類似的問(wèn)題。比如說(shuō)你正在為一個(gè)Web項(xiàng)目寫Javascript,但是中間你發(fā)現(xiàn)了jQuery,這時(shí)候你會(huì)迫不及待想把jQuery應(yīng)用進(jìn)去,而丟掉原來(lái)的Javascript代碼,即便你根本沒用jQuery寫過(guò)任何項(xiàng)目。
***的方式是你先用jQuery學(xué)著寫一些簡(jiǎn)單的例子,把你項(xiàng)目中要用到的技術(shù)都學(xué)會(huì)。比如說(shuō)你想要用AJAX?就先在項(xiàng)目之外寫一些關(guān)于AJAX的簡(jiǎn)單例子,等到完全掌握了,就可以將老代碼從項(xiàng)目中移除。
如果你熱衷于編程,我強(qiáng)烈推薦你閱讀Steve McConnell編寫的《Code Complete》,它將永遠(yuǎn)改變你的編程思維。
本文推薦:http://my.oschina.net/LittleDY/blog/304107




























