W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
學而不思則罔,思而不學則殆??鬃印墩撜Z》
過去的程序員忍者使用這些技巧,來使代碼維護者的頭腦更加敏銳。
代碼審查大師在測試任務中尋找它們。
一些新入門的開發(fā)者有時候甚至比忍者程序員能夠更好地使用它們。
仔細閱讀本文,找出你是誰 —— 一個忍者、一個新手、或者一個代碼審查者?
檢測到諷刺意味
許多人試圖追隨忍者的腳步。只有極少數(shù)成功了。
把代碼盡可能寫得短。展示出你是多么的聰明啊。
在編程中,多使用一些巧妙的編程語言特性。
例如,看一下這個三元運算符 ?'?'
?:
// 從一個著名的 JavaScript 庫中截取的代碼
i = i ? i < 0 ? Math.max(0, len + i) : i : 0;
很酷,對嗎?如果你這樣寫了,那些看到這一行代碼并嘗試去理解 ?i
? 的值是什么的開發(fā)者們,就會有一個“快活的”的時光了。然后會來找你尋求答案。
告訴他短一點總是更好的。引導他進入忍者之路。
道隱無名。夫唯道善貸且成。老子(道德經(jīng))
另一個縮減代碼量的方法是,到處使用單字母的變量名。例如 ?a
?、?b
?或 ?c
?。
短變量就像森林中真正的忍者一樣,一下就找不到了。沒有人能夠通過編輯器的“搜索”功能找到它。即使有人做到了,他也不能“破譯”出變量名 ?a
? 或 ?b
? 到底是什么意思。
……但是有一個例外情況。一個真正的忍者絕不會在 ?"for"
? 循環(huán)中使用 ?i
?作為計數(shù)器。在任何地方都可以,但是這里不會用。你隨便一找,就能找到很多不尋常的字母。例如 ?x
?或 ?y
?。
使用一個不尋常的變量多酷啊,尤其是在長達 1-2 頁(如果可以的話,你可以寫得更長)的循環(huán)體中使用的時候。如果某人要研究循環(huán)內(nèi)部實現(xiàn)的時候,他就很難很快地找出變量 ?x
?其實是循環(huán)計數(shù)器啦。
如果團隊規(guī)則中禁止使用一個字母和模糊的命名 — 那就縮短命名,使用縮寫吧。
像這樣:
list
?→ ?lst
?userAgent
?→ ?ua
?browser
?→ ?brsr
?只有具有真正良好直覺的人,才能夠理解這樣的命名。盡可能縮短一切。只有真正有價值的人,才能夠維護這種代碼的開發(fā)。
大方無隅,大器晚成,大音希聲,大象無形。老子(道德經(jīng))
當選擇一個名字時,盡可能嘗試使用最抽象的詞語。例如 ?obj
?、?data
?、?value
?、?item
?和 ?elem
?等。
data
?。 在任何能用的地方都使用它。的確,每個變量都持有 數(shù)據(jù)(data),對吧?……但是 ?data
?已經(jīng)用過了怎么辦?可以嘗試一下 ?value
?,它也很普遍。畢竟,一個變量總會有一個 值(value),對吧?str
?、?num
?……嘗試一下吧。新手可能會詫異 — 這些名字對于忍者來說真的有用嗎?事實上,有用的!一方面,變量名仍然有著一些含義。它說明了變量內(nèi)是什么:一個字符串、一個數(shù)字或是其他的東西。但是當一個局外人試圖理解代碼時,他會驚訝地發(fā)現(xiàn)實際上沒有任何有效信息!最終就無法修改你精心思考過的代碼。我們可以通過代碼調(diào)試,很容易地看出值的類型。但是變量名的含義呢?它存了哪一個字符串或數(shù)字?如果思考的深度不夠,是沒有辦法搞明白的。data1
?, ?item2
?, ?elem5
?……只有一個真正細心的程序員才能理解你的代碼。但是怎么檢驗呢?
方式之一 —— 使用相似的變量名,像 ?date
?和 ?data
?。
盡你所能地將它們混合在一起。
想快速閱讀這種代碼是不可能的。并且如果有一個錯別字時……額……我們卡在這兒好長時間了,到飯點了 (⊙v⊙)。
道,可道,非常道。名,可名,非常名。老子《道德經(jīng)》
對 同一個 東西使用 類似 的命名,可以使生活更有趣,并且能夠展現(xiàn)你的創(chuàng)造力。
例如,函數(shù)前綴。如果一個函數(shù)的功能是在屏幕上展示一個消息 — 名稱可以以 ?display…
? 開頭,例如 ?displayMessage
?。如果另一個函數(shù)展示別的東西,比如一個用戶名,名稱可以以 ?show…
? 開始(例如 ?showName
?)。
暗示這些函數(shù)之間有微妙的差異,實際上并沒有。
與團隊中的其他忍者們達成一個協(xié)議:如果張三在他的代碼中以 ?display...
? 來開始一個“顯示”函數(shù),那么李四可以用 ?render..
?,王二可以使用 ?paint...
?。你可以發(fā)現(xiàn)代碼變得多么地有趣多樣呀。
……現(xiàn)在是帽子戲法!
對于有非常重要的差異的兩個函數(shù) — 使用相同的前綴。
例如,?printPage(page)
? 函數(shù)會使用一個打印機(printer)。?printText(text)
? 函數(shù)會將文字顯示到屏幕上。讓一個不熟悉的讀者來思考一下:“名字為 ?printMessage(message)
? 的函數(shù)會將消息放到哪里呢?打印機還是屏幕上?”。為了讓代碼真正耀眼,?printMessage(message)
? 應該將消息輸出到新窗口中!
始制有名,名亦既有,夫亦將知止,知止可以不殆。老子(道德經(jīng))
僅在絕對必要時才添加新變量。
否則,重用已經(jīng)存在的名字。直接把新值寫進變量即可。
在一個函數(shù)中,嘗試僅使用作為參數(shù)傳遞的變量。
這樣就很難確定這個變量的值現(xiàn)在是什么了。也不知道它是從哪里來的。目的是提高閱讀代碼的人的直覺和記憶力。一個直覺較弱的人必須逐行分析代碼,跟蹤每個代碼分支中的更改。
這個方法的一個進階方案是,在循環(huán)或函數(shù)中偷偷地替換掉它的值。
例如:
function ninjaFunction(elem) {
// 基于變量 elem 進行工作的 20 行代碼
elem = clone(elem);
// 又 20 行代碼,現(xiàn)在使用的是 clone 后的 elem 變量。
}
想要在后半部分中使用 ?elem
?的程序員會感到很詫異……只有在調(diào)試期間,檢查代碼之后,他才會發(fā)現(xiàn)他正在使用克隆過的變量!
經(jīng)??吹竭@樣的代碼,即使對經(jīng)驗豐富的忍者來說也是致命的。
在變量名前加上下劃線 ?_
? 和 ?__
?。例如 ?_name
? 和 ?__value
?。如果只有你知道它們的含義,那就非常棒了?;蛘?,加這些下劃線只是為了好玩兒,沒有任何含義,那就更棒了!
加下劃線可謂是一箭雙雕。首先,代碼變得更長,可讀性更低;并且,你的開發(fā)者小伙伴可能會花費很長時間,來弄清楚下劃線是什么意思。
聰明的忍者會在代碼的一個地方使用下劃線,然后在其他地方刻意避免使用它們。這會使代碼變得更加脆弱,并提高了代碼未來出現(xiàn)錯誤的可能性。
向大家展現(xiàn)一下你那豐富的情感!像 ?superElement
?、?megaFrame
?和 ?niceItem
?這樣的名字一定會啟發(fā)讀者。
事實上,從一方面來說,看似寫了一些東西:?super..
?、?mega..
?、?nice..
?。但從另一方面來說 — 并沒有提供任何細節(jié)。閱讀代碼的人可能需要耗費一到兩個小時的帶薪工作時間,冥思苦想來尋找一個隱藏的含義。
處明者不見暗中一物,處暗者能見明中區(qū)事。關(guān)尹子
對函數(shù)內(nèi)部和外部的變量,使用相同的名稱。很簡單,不用費勁想新的名稱。
let user = authenticateUser();
function render() {
let user = anotherValue();
...
...許多行代碼...
...
... // <-- 某個程序員想要在這里使用 user 變量……
...
}
在研究 ?render
? 內(nèi)部代碼的程序員可能不會注意到,有一個內(nèi)部變量 ?user
?屏蔽了外部的 ?user
?變量。
然后他會假設(shè) ?user
?仍然是外部的變量然后使用它,?authenticateUser()
?的結(jié)果……陷阱出來啦!你好呀,調(diào)試器……
有些函數(shù)看起來它們不會改變?nèi)魏螙|西。例如 ?isReady()
?,?checkPermission()
?,?findTags()……
?它們被假定用于執(zhí)行計算、查找和返回數(shù)據(jù),而不會更改任何它們自身之外的數(shù)據(jù)。這被稱為“無副作用”。
一個非常驚喜的技巧就是,除了主要任務之外,給它們添加一個“有用的”行為。
當你的同事看到被命名為? is..
?、?check..
? 或 ?find...
? 的函數(shù)改變了某些東西的時候,他臉上肯定是一臉懵逼的表情 — 這會擴大你的理性界限。
另一個驚喜的方式是,返回非標準的結(jié)果。
展示你原來的想法!讓調(diào)用 ?checkPermission
?時的返回值不是 ?true/false
?,而是一個包含檢查結(jié)果的復雜對象。
那些嘗試寫 ?if (checkPermission(..))
? 的開發(fā)者,會很疑惑為什么它不能工作。告訴他們:“去讀文檔吧”。然后給出這篇文章。
大道泛兮,其左可右。老子(道德經(jīng))
不要讓函數(shù)受限于名字中寫的內(nèi)容。拓寬一些。
例如,函數(shù) ?validateEmail(email)
? 可以(除了檢查郵件的正確性之外)顯示一個錯誤消息并要求重新輸入郵件。
額外的行為在函數(shù)名稱中不應該很明顯。一個真正的忍者會使它們在代碼中也不明顯。
將多個行為合并到一起,可以保護你的代碼不被重用。
想象一下,另一個開發(fā)者只想檢查郵箱而不想輸出任何信息。你的函數(shù) ?validateEmail(email)
? 對他而言就不合適啦。所以他不會找你問關(guān)于這些函數(shù)的任何事而打斷你的思考。
上面的所有“建議”都是從真實的代碼中提煉而來的……有時候,這些代碼是由有經(jīng)驗的開發(fā)者寫的。也許比你更有經(jīng)驗 ;)
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: