"閱讀本文大約需要 5 分鐘"
很多程序員在學(xué)習(xí)一門新的編程語(yǔ)言時(shí),會(huì)先學(xué)習(xí)基礎(chǔ)的語(yǔ)法和自帶的基礎(chǔ)庫(kù),稍加熟練后便會(huì)在實(shí)際工作中使用,在實(shí)踐中再繼續(xù)提升。
但是在這里,我們需要明確一個(gè)概念,就是熟練掌握某種編程語(yǔ)言,并不意味著所寫出的代碼的可讀性,可維護(hù)性是好的。同樣的,功能正確,性能良好的代碼也不一定是易懂,易維護(hù)的,在某種程度而言上面這些特性是正交的,彼此并沒(méi)有特定的聯(lián)系。
在工作 2,3 年后,把功能代碼寫對(duì)不是什么太大的問(wèn)題,但是和一些能力較強(qiáng)的程序員的代碼,或是優(yōu)秀的開源框架的代碼相比,拋開架構(gòu)層面的優(yōu)劣不談,在最基礎(chǔ)的代碼層面,你隱隱的發(fā)現(xiàn)總是有些區(qū)別,但是可能你很難用具體的語(yǔ)言表達(dá)出這差的到底是什么。
我把這些差異很大部分歸因于代碼的可讀性問(wèn)題,而可讀性體現(xiàn)在代碼的方方面面,小到一個(gè)變量的命名,大到如何編寫循環(huán),組織函數(shù)和類的層次結(jié)構(gòu)。正是由于這些細(xì)微的問(wèn)題,積少成多,會(huì)在總體上讓你的代碼和優(yōu)秀的代碼從看到的第一眼開始就分了高低。
市面上從不缺少教授各種編程語(yǔ)言和框架的書籍,也有很多介紹系統(tǒng)架構(gòu)的書,但是真正告訴你如何寫出「漂亮」,易懂,專業(yè)代碼書卻很少。之前推薦過(guò)的 <<重構(gòu)>> 算一本,而今天推薦的 <<編寫可讀代碼的藝術(shù)>> (后文簡(jiǎn)稱藝術(shù)) 也是一本講述如何「寫好」代碼的書。這本書雖然很薄,200 頁(yè)都不到,周末兩天一定能看完,但是其中內(nèi)容卻非常的實(shí)用。本書的兩位作者都來(lái)自 Google,因此編碼的經(jīng)驗(yàn)和技能毋庸置疑,但是你也不用擔(dān)心無(wú)法理解書里講解的技巧和思想。作者/譯者實(shí)用的語(yǔ)言風(fēng)趣淺顯,配上幽默的漫畫,要想不懂才是難事。
<<藝術(shù)>> 從 4 個(gè)方面來(lái)闡述如何提升代碼的可讀性,從最基礎(chǔ)的變量,函數(shù)如何命名,到如何編寫注釋,如何簡(jiǎn)化循環(huán)和邏輯,直到重新組織代碼,可謂囊括了日常編碼和設(shè)計(jì)技巧中最為實(shí)用的幾個(gè)部分。下面是一些我個(gè)人印象比較深也覺(jué)得對(duì)大部分編程語(yǔ)言也適用的技巧。
[first, last] 和 [begin, end]
有時(shí)候你會(huì)編寫一些與范圍相關(guān)的代碼,比如時(shí)間范圍,數(shù)字范圍。而牽涉到范圍的邏輯一般都會(huì)有開閉區(qū)間的問(wèn)題,如果是你,你怎么編寫清晰的代碼來(lái)告訴使用者理解這些范圍邏輯呢?書中給出了大部分框架和類庫(kù)中約定俗成的建議,即實(shí)用 first, last 來(lái)表示兩個(gè)閉區(qū)間的變量,而使用 begin, end 來(lái)表示前閉后開的區(qū)間邏輯。使用這樣的命名方法是不是讓自己的代碼一下子有些專業(yè)的感覺(jué)呢?
代碼的段落
其實(shí)寫代碼和寫文章一樣,也講究段落分明,這樣才能讓讀者更清晰的了解代碼的意圖,不信?看一下下面兩段內(nèi)容一樣的代碼,是不是給你帶來(lái)不同的感覺(jué)?
# Import the user's email contacts, and match them to users in our system.
# Then display a list of those users that he/she isn't already friends with.
def suggest_new_friends(user, email_password):
friends = user.friends()
friend_emails = set(f.email for f in friends)
contacts = import_contacts(user.email, email_password)
contact_emails = set(c.email for c in contacts)
non_friend_emails = contact_emails - friend_emails
suggested_friends = User.objects.select(email__in=non_friend_emails)
display['user'] = user
display['friends'] = friends
display['suggested_friends'] = suggested_friends
return render("suggested_friends.html", display)
def suggest_new_friends(user, email_password):
# Get the user's friends' email-addresses.
friends = user.friends()
friend_emails = set(f.email for f in friends)
# Import all email address from this user's email acount.
contacts = import_contacts(user.email, email_password)
contact_emails = set(c.email for c in contacts)
# Find matching users that they aren't already friends with.
non_friend_emails = contact_emails - friend_emails
suggested_friends = User.objects.select(email__in=non_friend_emails)
# Display these lists on the page.
display['user'] = user
display['friends'] = friends
display['suggested_friends'] = suggested_friends
return render("suggested_friends.html", display)
兩段相同內(nèi)容的 python 代碼,這是第二段合理的使用了空行這樣簡(jiǎn)單的技巧,將函數(shù)內(nèi)不同部分的邏輯在視覺(jué)上進(jìn)行分割,就大大提升了代碼的可讀性,這樣的技巧是不是簡(jiǎn)單易學(xué),但是效果明顯?
控制流程
在日常編程中,if...else 語(yǔ)句一定是出現(xiàn)頻率最高的語(yǔ)句之一。但是往往 if 這種邏輯分支又是在理解代碼過(guò)程只能夠較為耗費(fèi)腦力的部分,如何提升這種語(yǔ)句的可讀性呢?不妨看看 <<藝術(shù)>> 給出的建議。
-
if語(yǔ)句中首先處理「正邏輯」部分,即第一個(gè)分支處理分支條件為true的分支,因?yàn)橐话阍诶斫庹噙壿嫊r(shí)較為簡(jiǎn)單 - 盡量使用
return提早從分支結(jié)構(gòu)中返回,并減少else的使用,參考下面的示例:
public boolean Contains(String str, String substr) {
if (str == null || substr == null) return false;
if (substr.equals("")) return true;
...
}
- 較少
if...else語(yǔ)句中嵌套的層數(shù),最好沒(méi)有嵌套??纯聪旅媲短椎?if...else邏輯是不是挺難理解的?
if (user_result == SUCCESS {
if (permission_result != SUCCESS) {
reply.WriteErrors("error reading permissions");
reply.Done();
return;
}
reply.WriteErrors("");
} else {
reply.WriteErrors(user_result);
}
reply.Done();
那到底怎么改呢?你不妨自己先試一下,然后去書中尋找答案,看看是不是與作者想的一樣呢?
書中還介紹了很多類似我提到的技巧和最佳實(shí)踐,我個(gè)人讀到這本書的時(shí)候有些相見(jiàn)恨晚的感覺(jué)。因?yàn)槠渲杏行┘记墒俏易约郝鞯?,也有些是其他同事教給我的,假如我能早些讀到這本書會(huì)節(jié)約我大量的時(shí)間。想寫出易讀,「漂亮」,專業(yè)代碼的你,不妨找一個(gè)周末,靜下心來(lái),仔細(xì)的閱讀這本 <<編寫可讀代碼的藝術(shù)>>,我想結(jié)果不會(huì)令你失望。不積硅步無(wú)以至千里,想當(dāng)架構(gòu)師,先把代碼寫好吧!
如果你想學(xué)習(xí)某些計(jì)算機(jī)相關(guān)的知識(shí),缺不知道要去看哪些經(jīng)典的書籍,不妨后臺(tái)聯(lián)系我吧,我一定會(huì)推薦你最適合你的好書,幫你事半功倍,飛速成長(zhǎng)!
