《編寫可讀代碼的藝術(shù)》讀書筆記(一)

0. 前言

程序員給人的印象大多都是蓬頭垢面,衣著隨意家夺。然而脱柱,我認(rèn)為一個優(yōu)秀的程序員對于代碼一定有他的審美。如果你做過很多項目拉馋,寫過多年的代碼榨为,對程序還僅僅是停留在能夠跑通,能實現(xiàn)某個功能就算完成了煌茴,對于代碼的是否足夠elegant沒有任何的追求随闺,我認(rèn)為你不過就是一個code monkey。其實市面上類似的書有很多蔓腐,例如《clean code》矩乐,這本書在深度上可能與《clean code》相比還有所不及,但在廣度上,遠(yuǎn)遠(yuǎn)超過了《clean code》散罕。因為它關(guān)注的是編碼本身分歇,所以并不局限于一種編程語言。作者對于代碼的精雕細(xì)琢已經(jīng)達(dá)到了一種令人發(fā)狂的地步欧漱,仿佛代碼本身就是一件藝術(shù)品职抡。如果你對于代碼的腐爛有著一種敏銳的嗅覺,并且具有一種強(qiáng)迫癥误甚,想要努力去重構(gòu)它缚甩,那么恭喜你,這本書適合你窑邦。最后我想引用軟件設(shè)計大師Martin Fowler在他的《Refactoring : Improving the Design of Existing Code》中的一句話:

任何一個傻瓜都能寫出計算機(jī)可以理解的程序蹄胰,只有寫出人類容易理解的程序才是優(yōu)秀的程序員。

1.把信息裝在名字里

無論是名字變量奕翔、函數(shù)還是類,都可以使用很多相同的原則浩蓉。我們喜歡把名字當(dāng)作一個小小的注釋派继。盡管空間不算很大,但選擇一個好名字可以讓它承載很多的信息捻艳。

1.1選擇專業(yè)的名詞

“把信息裝在名字中”包括要選擇非常專業(yè)的詞驾窟,并且避免使用“空洞”的詞,例如认轨,“get”這個詞就非常不專業(yè)绅络,例如下面的例子:

def getPage(url):...

“get”這個詞沒有表達(dá)出很多信息。這個方法是從本次緩存中得到一個頁面嘁字,還是從數(shù)據(jù)庫中恩急,或者從互聯(lián)網(wǎng)中,更專業(yè)的名詞可以使FetchPage()或者DownloadPage()纪蜒。

1.2 找到更優(yōu)表現(xiàn)力的詞

下面是一些例子衷恭,這些單詞更有表現(xiàn)力,可能適合你的語境:

單詞 更多選擇
send deliver纯续、dispatch随珠、announce、distribute猬错、route
find search窗看、extract、locate倦炒、recover
start launch显沈、create、begin析校、open
make create构罗、set up铜涉、build、generate遂唧、compose芙代、add、new
1.3 避免像tmp和retval這樣泛泛的名字

使用像tmp盖彭、retval和foo這樣的名字往往是“我想不出名字”的托辭纹烹。

建議
retval這個名字沒有包含很多信息。用一個描述該變量的值的名字來代替它召边。

然而铺呵,在循環(huán)迭代器中,像i隧熙、j片挂、iter等名字常用作索引和循環(huán)迭代器。盡管這些名字很空泛贞盯,但是大家都知道它們的意思是“我是一個迭代器”音念。

1.4 用具體的名字代替抽象的名字

例如,假設(shè)你有一個內(nèi)部方法叫做serverCanStart()躏敢,它檢測服務(wù)是否可以監(jiān)聽某個TCP/IP端口闷愤。然而serverCanStart()有點抽象。canListenOnPort()就更具體一些件余。

1.5 為名字附帶更多信息

我們前面提到讥脐,一個變量名就像是一個小小的注釋。下表給出更多需要給名字附加上額外信息的例子:

情形 變量名 更好的名字
一個“純文本”格式的密碼啼器,需要加密后才能進(jìn)一步使用 password plaintext_password
一條用戶提供的注釋旬渠,需要轉(zhuǎn)義之后才能用于顯示 comment unescaped_comment
已轉(zhuǎn)化為UTF-8格式的html字節(jié) html html_utf8
1.6 在小的作用域里可以使用短的名字

作用域小的標(biāo)識符不用帶上太多信息,因為所有信息(變量的類型镀首、它的初值坟漱、如何析構(gòu)等)都很容易看到,所以可以用很多的名字更哄。

1.7 利用名字的格式來傳遞含義

例如在Java中芋齿,通常以字母全部大寫加下劃線的形式表示常量(CONSTANT_NAME)。再比如成翩,給jQuery返回的結(jié)果通常會加上$作為前綴觅捆。

2. 不會誤解的名字

關(guān)鍵思想
要多問自己幾遍:“這個名字會被別人解讀成其他的含義嗎?”要仔細(xì)審視這個名字麻敌。

2.1 推薦用min和max來標(biāo)識(包含)的極限

加入你的購物車應(yīng)用程序最多不能超過10件物品:

MAX_ITEM_IN_CART = 10

if shopping_cart.num_items() > MAX_ITEM_IN_CART:
    Error("Too many items in cart.")
2.2 推薦用begin和end來表示包含/排除范圍

因為對begin/end的使用是如此常見栅炒,至少在c++標(biāo)準(zhǔn)庫中是這樣的,還有大多數(shù)需要分片的數(shù)組也是這樣用的,它已經(jīng)是最好的選擇了赢赊。

2.3 給布爾值命名

當(dāng)為布爾值變量或者返回布爾值的函數(shù)選擇名字時乙漓,要確保返回true和false的意義很明確。通常來講释移,加上像is叭披、has、can玩讳、should這樣的詞涩蜘,可以把布爾值變得很明確。

2.4 與使用者的期望相匹配

很多程序員都習(xí)慣了把以get開始的方法當(dāng)作“輕量級訪問器”這樣的用法熏纯,它只是簡單地返回一個內(nèi)部成員變量同诫。如果違背這個習(xí)慣很可能會誤導(dǎo)用戶。

以下是一個用Java寫的例子樟澜,請不要這樣做:

public class StatisticsConllector {
    public double getMean() {
        // Iterate through all samples and retuan total / num_samples
    }
}

在這個例子中误窖,getMean()的實現(xiàn)是要遍歷所有經(jīng)過的數(shù)據(jù)并同時計算中值。如果有大量的數(shù)據(jù)的話秩贰,這樣的一步可能會有很大的代價贩猎!但一個容易輕信的程序員可能會隨意地調(diào)用getMean(),還以為是個沒什么代價的調(diào)用萍膛。

3. 審美

好的源代碼應(yīng)當(dāng)“看上去養(yǎng)眼”。使用好的留白嚷堡、對齊及順序可以讓你的代碼更容易閱讀蝗罗。
確切地說,有三條原則:

  1. 使用一致的布局蝌戒,讓讀者很快就習(xí)慣這種風(fēng)格串塑。
  1. 讓相似的代碼看上去相似。
  1. 把相關(guān)的代碼行分組北苟,形成代碼塊桩匪。

4. 該寫什么樣的注釋

當(dāng)你寫代碼時,你的腦海里有很多有價值的信息友鼻。當(dāng)其他人讀你的代碼時傻昙,這些信息已經(jīng)丟失了,他們所見到的只是眼前的代碼彩扔。

關(guān)鍵思想
注釋的目的是盡量幫助讀者了解得和作者一樣多妆档。

4.1 什么不需要注釋

下面代碼中的注釋沒有任何價值:

# remove everything after the second '*'
name = '*'.join(line.split('*')[:2])

從技術(shù)上講,這里的注釋沒有表達(dá)出任何新信息虫碉。不要為那些從代碼本身就能快速推斷的事實寫注釋贾惦。

4.2 不要給不好的名字加注釋——應(yīng)該把名字改好

注釋不應(yīng)該應(yīng)用于粉飾不好的名字,我們完全可以用一個更加自我說明的名字。寫代碼的人常常把這條規(guī)則表述為:好代碼>壞代碼+好注釋

4.3 記錄你的思想

現(xiàn)在知道了什么不需要注釋须板,下面討論什么需要注釋碰镜。
很多好的注釋僅通過“記錄你的想法”就能得到,也就是那些你在寫代碼時有過的重要的想法习瑰。下面是一個例子:

//出乎意外的是绪颖,對于這些數(shù)據(jù)用二叉樹比用哈希表快40%
//哈希運算的代價比左/右比較大得多

這段注釋教會讀者一些事情,并且防止他們?yōu)闊o謂的優(yōu)化而浪費時間杰刽。

4.4 為代碼中的瑕疵寫注釋

代碼始終在演進(jìn)菠发,并且在這過程中肯定會有瑕疵。不要不好意思把這些瑕疵記錄下來贺嫂。
例如滓鸠,當(dāng)代碼需要改進(jìn)時:
// TODO:采用更快的算法
或者當(dāng)代碼沒有完成時:
// TODO(dustin):處理除JPEG以外的圖像格式

4.5 “全局觀”注釋

對于團(tuán)隊的新成員來講,最難的事情之一就是理解“全局觀”第喳,類之間如何交互糜俗,數(shù)據(jù)如何在整個系統(tǒng)中流動,以及入口點在哪里曲饱。設(shè)計系統(tǒng)的人經(jīng)常忘記給這些東西加注釋悠抹,“只緣身在此山中”。下面是一個文件級別注釋的簡單例子:

    // 這個文件包含一些輔助函數(shù)扩淀,為我們的文件系統(tǒng)提供了更便利的接口
   // 它處理了文件權(quán)限及其他基本的細(xì)節(jié)楔敌。
4.6 總結(jié)性注釋

全局觀注釋代表文件級別的注釋,就算在一個函數(shù)的內(nèi)部驻谆,寫一個總結(jié)性的注釋也是個不錯的注意卵凑,使讀者不至迷失在細(xì)節(jié)中。這段注釋巧妙的總結(jié)了其后的底層代碼:

#Find all the item that customers purchase for themselves
for customers_id in all_customers:
    for sale in all_sales[customer_id].sales:
        if sales.recipient == customer_id:
            ....
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末胜臊,一起剝皮案震驚了整個濱河市勺卢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌象对,老刑警劉巖黑忱,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異勒魔,居然都是意外死亡甫煞,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進(jìn)店門冠绢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來危虱,“玉大人,你說我怎么就攤上這事唐全“u危” “怎么了蕊玷?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長弥雹。 經(jīng)常有香客問我垃帅,道長,這世上最難降的妖魔是什么剪勿? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任贸诚,我火速辦了婚禮,結(jié)果婚禮上厕吉,老公的妹妹穿的比我還像新娘酱固。我一直安慰自己,他們只是感情好头朱,可當(dāng)我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布运悲。 她就那樣靜靜地躺著,像睡著了一般项钮。 火紅的嫁衣襯著肌膚如雪班眯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天烁巫,我揣著相機(jī)與錄音署隘,去河邊找鬼。 笑死亚隙,一個胖子當(dāng)著我的面吹牛磁餐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播阿弃,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼崖媚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了恤浪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤肴楷,失蹤者是張志新(化名)和其女友劉穎水由,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體赛蔫,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡砂客,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了呵恢。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鞠值。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖渗钉,靈堂內(nèi)的尸體忽然破棺而出彤恶,到底是詐尸還是另有隱情钞钙,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布声离,位于F島的核電站芒炼,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏术徊。R本人自食惡果不足惜本刽,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望赠涮。 院中可真熱鬧子寓,春花似錦、人聲如沸笋除。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽株憾。三九已至蝙寨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間嗤瞎,已是汗流浹背墙歪。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留贝奇,地道東北人虹菲。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像掉瞳,于是被迫代替她去往敵國和親毕源。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,925評論 2 344

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

  • 第一部分 打好基礎(chǔ) Laying the Foundation 第一章 歡迎進(jìn)入軟件構(gòu)建的世界 Welcome t...
    白樺葉閱讀 4,600評論 0 17
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理陕习,服務(wù)發(fā)現(xiàn)霎褐,斷路器,智...
    卡卡羅2017閱讀 134,601評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法该镣,類相關(guān)的語法冻璃,內(nèi)部類的語法,繼承相關(guān)的語法损合,異常的語法省艳,線程的語...
    子非魚_t_閱讀 31,587評論 18 399
  • 幾經(jīng)流年 我褪去了稚子的身份 步入了滿是荊棘的社會 終于 獨當(dāng)一面 成為我們生存的法則 諸多時候 選擇與被選擇 讓...
    笙筱呦閱讀 232評論 1 6
  • 題: 孩子身上的問題都是我的問題。 抱團(tuán)挑戰(zhàn)日記第53天嫁审。讀經(jīng)時間:2017.4.19跋炕。讀經(jīng)典內(nèi)容有:《易經(jīng)...
    羅石緣閱讀 135評論 0 0