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