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

不管你是轉行也好,初學也罷,進階也可——【值得點擊進入】的程式員編程學習俱樂部
涉及到:C語言、C++、windows編程、網路編程、QT界面開發、Linux編程、游戲編程、黑客等等......

一個活躍、高格調、高層次的程式員編程學習殿堂;編程入門只是順帶,思維的提高才有價值!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/208625.html
標籤:其他
上一篇:從零開始搭建 PHP 原生環境(Windows 篇)
下一篇:剛接觸python的小白
