《編寫可讀代碼的藝術(shù)》是與Clean Code相似的書歧沪,提供改善“丑陋”代碼的技巧。本書193頁幅聘,共16章內(nèi)容捺疼。
本書分為四個部分:
- 表面層次的改進-命名/注釋以及審美
- 簡化循環(huán)和邏輯
- 重新組織代碼
- 精選話題
關(guān)鍵思想:代碼應當易于理解
可讀性基本定律:代碼的寫法應當使別人理解他所需的時間最小化。
1 表面層次的改進
包括好的名字怎爵,好的注釋特石,還有好的格式
1.1 把信息裝進名字里
1.1.1 選擇專業(yè)的詞
反例: 函數(shù)名 GetPage(url)
正例: FetchPage()、DownloadPage()
反例: class BinaryTree的方法Size() VS
正例:Hight() NumberNodes(),MemoryBytes()
反例: class Thread的方法Stop()
正例: Kill() Pause(),Resume()
1.1.2 避免泛泛的名字
關(guān)鍵思想:清新和準確比裝可愛好
迭代器變量疙咸,應該有明確指向
避免tmp和retcode泛泛的名字
retcode建議:retcode沒有包含更新信息县匠。描述該變量的值的名字代替它。
tmp建議:tmp這個名字只應用于短期存在且臨時性為其主要存在因素的變量。
如果需要使用tmp乞旦,也需要指明tmp_file贼穆,或者tmp_data.
迭代器變量,應該有明確指向
1.1.3 用具體的名字代替抽象的名字
反例: 函數(shù)ServerCanStart:檢測服務是否可以監(jiān)聽某個端口
正例: CanListenOnPort()
1.1.4 給名字附帶更多的信息
1兰粉、一個變量名就是一個小小的注釋
反例:string id 喉誊; //example:"0x128a232b"
正例:string hex_id;
2、變量名帶單位
3摔桦、附帶額外信息
1.1.5 決定名字的長度
名字隱含約束就是不能太長液肌。
- 1、在小的作用域可以使用短名字焰络。
- 2戴甩、輸入長名字不再是問題∩帘耍【內(nèi)置補全功能】
- 3甜孤、首字母縮寫詞和縮寫
經(jīng)驗原則:團隊新成員可以理解這個名字含義。 - 4畏腕、丟掉沒用的詞
反例 :ConvertToString()
正例: ToString()
1.1.6 利用名字的格式表達含義
利用下劃線缴川,大小寫或者連字符可以裝載更多含義。 在google的C++代碼規(guī)范中:
- kMaxOpenFiles表示常量描馅,MAX_OPEN_FILES表示宏
- state是局部變量把夸,state_是成員變量
1.1.7 小結(jié)
- 使用專業(yè)的單詞
- 避免空泛的名字
- 使用具體的名字描述細致的事物
- 給名字帶上重要的細節(jié)
- 給作用域更大的名字采用更長的名字
- 有目的使用大小寫和下劃線
1.2 不起誤解的名字
關(guān)鍵思想:要多問自己幾遍,“這個名字會被別人誤解成其他含義嗎铭污?“要仔細審視這個名字
反例: Filter("years <= 2010") 挑出還是減掉恋日?
反例: Clip(text,length)是截斷到况凉,還是去掉谚鄙?
正例:使用min和max表示極限
正例:使用first和last表示包含的范圍
正例:使用begin和end表示包含/排除的范圍
布爾型命名
正例:加上is,should刁绒,has闷营,can,use變得含義更明確
正例:避免使用反義名詞:bool disable_ssl=false;
1.3 審美
布局的三個原則:
- 使用一致的布局知市,讓讀者很快習慣這種風格傻盟。
- 讓相似代碼看上去相似。
- 相關(guān)的代碼分組嫂丙,形成代碼塊娘赴。
- 1、使用【從審美角度】讓人愉悅的代碼更容易
- 2跟啤、安排換行是節(jié)奏保持一致和緊湊
-
3诽表、用方法規(guī)整不一致的東西
-
4唉锌、在需要時,使用列對齊
- 5竿奏、選擇有意義的順序袄简,并保持一致
- 6、把申明按照塊組織起來
- 7泛啸、把代碼分成段落
- 8绿语、一致性比”正確“風格更重要
1.4 注釋
關(guān)鍵思想:注釋的目的就是盡量幫讀者和作者了解一樣多
1、什么不需要注釋
- 不要為那些可以從代碼快速推斷的事實寫注釋
- 不要為了注釋而注釋
- 不要為不好的名字加注釋候址,應該把名字改好
2吕粹、記錄你的思想
- 加入“導演評論”
-
為代碼的瑕疵做注釋(//TODO:)
- 給常量加注釋
常量本身不需要解釋,記錄決定這個常量取值的想法岗仑,便于后續(xù)優(yōu)化匹耕。
3、站在讀者的角度
- 意料之中的提問
- 公布可能的陷阱
- 全局性的注釋
高級別的注釋信息赔蒲,包括文件泌神,類良漱,模塊如何組織工作的舞虱。 - 用注釋來總結(jié)代碼塊,防止迷失細節(jié)
1.5 寫出言簡意駭?shù)淖⑨?/h2>
關(guān)鍵思想:注釋應該有很高的信息/空間率
-
1母市、讓注釋保持緊湊
- 2矾兜、避免使用不明確的代詞(it,this)
- 3患久、潤色粗糙的句子
-
4椅寺、精確描述函數(shù)的行為
- 5、用輸入/輸出的例子來說明情況
-
6蒋失、申明代碼的意圖
【4返帕,5,6用單元測試代替注釋更妥】 -
7篙挽、具名函數(shù)參數(shù)的注釋
使用嵌入式的注釋荆萤,例如Function(/arg=/...)來解釋函數(shù)的參數(shù)。 - 8铣卡、采用信息量高的詞链韭,使得注釋簡潔
2 簡化循環(huán)和邏輯
2.1 把控制流變得易懂
關(guān)鍵思想:把條件,循環(huán)以及其它對控制流的改變做的越“自然”越好煮落。運用一種方式使得讀者不用停下來重讀你的代碼
-
1敞峭、條件語句中參數(shù)順序
if(length<=10) 還是 if(10>=length)?
while(bytes_expected < bytes_recieved) 還是 while(bytes_expected > bytes_recieved) ?
指導原則【和語言的語法一直】
比較的左側(cè) | 比較的右側(cè) |
---|---|
被詢問的表達式,它的值傾向于不斷變化 | 用來作比較的表達式蝉仇,它的值傾向于常量 |
if(object == null) 還是 if(null == object)?
2旋讹、if/else語句塊的順序
if條件選擇標準:
先處理正邏輯而不是負邏輯
先處理簡單的
先處理有趣或者可疑的3殖蚕、三目運算符
關(guān)鍵思想:相對于追求代碼最小行,一個更好的方式就是最小化人們理解他所需的時間
建議:默認情況下都if/else, 三目表達式只在最簡單的情況下使用沉迹。-
4嫌褪、避免do/while循環(huán)
使用while/for,而不是for/while, 把條件【危險】放到首先看到地方胚股。
5笼痛、從函數(shù)中提前返回
使用衛(wèi)語句,提前返回琅拌∮б粒【單出口】6、臭名昭著的goto
7进宝、最小化嵌套
思維棧-可能導致理解困難刻坊。
通過提前返回減少嵌套
減少循環(huán)內(nèi)的嵌套
2.2 拆分超長的表達式
1、解釋變量
引入變量來解釋子表達式党晋。
2谭胚、最小化嵌套
用一個變量來代替一段代碼。
3未玻、使用德摩根定理
4、濫用短路原理
5扳剿、使用德摩根定理
6旁趟、復雜表達式,提取函數(shù)庇绽,提前返回
2.3 變量和可讀性
1锡搜、減少變量
沒有價值的變量
減少中間結(jié)果
減少控制變量
2、變小變量的作用域
讓你的變量對盡量少的代碼行可見
C++ if的作用域
3耕餐、只寫一次的變量更好
操作一個變量的地方越多,越難確定他的值辟狈。
3 重新組織代碼
3.1 抽取不相干的子問題
抽取不相干的子問題肠缔,建議:積極地發(fā)現(xiàn)并抽取不相干的子邏輯。
我們指:
- 看到某個函數(shù)或者代碼塊上陕,問自己:這個代碼的高層次目標是什么桩砰?
- 對于每一行代碼,問:他是直接為了目標而工作嗎释簿?這段代碼高層次的目標是什么亚隅?
- 如果足夠的行數(shù)在解決不相干的子問題,抽取代碼到獨立的函數(shù)中庶溶。
- 抽取純工具代碼
- 其他多用途的代碼
- 創(chuàng)建大量通用代碼
- 項目專有代碼
- 簡化已有接口
- 按需重塑接口
-
避免過猶不及
小結(jié):把一般代碼和專有代碼分離煮纵。
3.2 一次只做一件事
- 1懂鸵、任務可以很小
- 2、從對象中抽取值
3.3 把想法變成代碼
愛因斯坦:如果你不能把一件事情解釋給你祖母聽的話說明你還沒有真正理解他
- 1行疏、像對著同事一樣匆光,用自然語言描述代碼要做什么。
- 2酿联、注意描述中所用的關(guān)鍵詞和短語终息。
- 3、寫出與描述匹配的代碼
3.4 少寫代碼
關(guān)鍵思想:最好讀的代碼就是沒有代碼贞让。
- 1別費神不需要的功能【過度設(shè)計】
- 2質(zhì)疑和拆分需求 【故事拆分】
- 3保持小代碼庫
利用工具減少重復代碼周崭,并刪除無用代碼
- 4、熟悉你周邊的庫
中肯建議:每隔一段時間喳张,花15分鐘來閱讀標準庫的所有函數(shù)/模塊/類型的名字续镇。
冒險、興奮-絕地武士追求的并不是這些销部。--尤達大師
4 精選話題
4.1 測試與可讀性
- 1摸航、使閱讀易于閱讀和理解
測試應該具備可讀性,以便其他程序員可以舒服的改變和增加用例舅桩。
對使用者隱去不重要的細節(jié)酱虎,以便重要的細節(jié)更突出。 - 2江咳、創(chuàng)建最小的測試申明
測試都可以提煉成:對于這樣的輸入/情形逢净,期望這樣的行為/輸出.【BDD的描述更好】 - 3、實現(xiàn)定制的“微語言”(DSL)
- 4歼指、讓錯誤消息具備可讀性
- 5、 手工打造錯誤消息
- 6甥雕、 測試函數(shù)命名
規(guī)則:Test_<Function>_<Situation> - 7踩身、TDD
易測試產(chǎn)生更好的代碼。
- 8挟阻、走的太遠
主要有:
為了可測試,犧牲可讀性
著迷100%可測試性
測試成為開發(fā)的阻礙
4.2 設(shè)計并改進
通過一個例子來說明:演進式改進的過程峭弟。
小結(jié)
本書2018讀的第一本書附鸽,大概花了10個多小時。本書在代碼可讀性的命名瞒瘸,布局坷备,注釋,循環(huán)控制情臭,抽取函數(shù)省撑,表達式赌蔑,可測試性方面都有很不錯的建議,值得內(nèi)部分享和學習竟秫。