如何編寫可讀性代碼

2019-08-16     AiChinaTech

作者:極鏈科技 湯紅燕

什麼叫可讀性代碼?

簡單來說,就是易於理解、耗腦時間少、可維護性較高的代碼。

編寫可讀性代碼

把信息裝到名字里(一個好的名字可以承載很多信息)

1. 選擇專業的詞(避免「空洞」)

比如函數 getUserInfo( ) 是用來獲取用戶信息,但是,是從接口中獲取的信息呢?還是在頁面已經暴露的信息?看到的時候就會有疑問。

命名的時候,如果是從網際網路中獲得,可以使用fetchUserInfo( )來表示。

2. 找到更有表現力的詞(更清晰、精確)

比如:search 和 find 區別 ,再可以類似於表格數據的篩選, 可以考慮用更準確的詞彙去表示。



避免使用像 tmp 和 retval 這樣泛泛的名字。

3. 使用具體的名字更細緻地描述事物

對於一個變量包含十六進位字符串,命名為 let id,但是為何不命名成 let hex_id?

如果你的變量時一個度量值的話,最好讓名字帶上它的單位。

4. 名字應該有多長

在編寫代碼取名的時候總會有一些疑問,我的定義名稱該多長才合適?可以遵循以下幾點:

l 小作用域裡可以使用短的名字;

l 首字母縮略詞和縮寫(當然是在成員能看懂的情況下 TBColor -> TextBackgroundColor);

l 丟掉沒用的詞(no-padding-all -> no-padding);

l 利用名字的格式來傳遞含義(比如所有的class 是class-name, id 是 id_id);

不會讓人誤解的名字

常用的 filter() 命名,如果新同學看到,可能會產生疑問,這是過濾掉滿足要求的值呢還是不滿足要求的?

為了便於處理以上情況,有以下幾點建議:

l 使用 min 和 max 來表示(包含)極限

l 使用 first 和 last 來表示包含的範圍

l 使用 begin 和 end 來表示包含/排除範圍

l 給布爾值命名

對於語句 bool read_password = true 是我們已經讀取密碼,還是我們需要讀取密碼?

這時候可以用 need_password 或 user_is_authenticated 這樣的名字來代替;

像 is 、has 、can或should這樣的詞,就可以把布爾值變得更明確。

審美

代碼的審美,確切地說,有三條原則:

1. 使用一致的布局,讓讀者很快就習慣這種風格。

2. 讓相似的代碼看上去相似。

3. 把相關的代碼行分組,形成代碼塊。

該寫怎樣的注釋

1. 從代碼本身快速推斷出事實的不需要注釋

2. 不要為了注釋而注釋

3. 不要給不好的名字加註釋(不如改名字)

4. 加入「導演評論」,你可以在代碼中加入注釋來記錄你對代碼有價值的見解。

5. 為代碼中的瑕疵寫注釋



6. 給常量加註釋(有些常量不需要注釋,因為它們的名字已經很清楚,但很多常量可以通過加註釋得以改進)

7. 站在讀者的角度,「全局觀」注釋



寫出言簡意賅的注釋

1. 讓注釋保持緊湊

2. 避免使用不明確的代詞(如it,this等)

3. 潤色粗糙的句子

4. 精確地描述函數的行為

比如用輸入/輸出例子來說明特別的情況

下面是一個用來移除部分字符串的通用函數:



5. 聲明代碼的意圖

對於「具名函數參數」的注釋,就是像 C# Python 這類語言的命名函數參數,讓每個參數的意義更加明確。

比如:



6. 採用信息含量高的詞

l 避免使用代詞

l 儘量精確描述函數的行為

l 精心挑選輸入/輸出的例子

l 聲明代碼的高層次意圖,而非明顯的細節

l 用嵌入注釋解釋難以理解的函數參數

l 用含義豐富的詞語

簡化循環和邏輯

1. 把控制流變得易讀

l 條件語句中參數的順序

比較左側: 「被詢問」的表達式,它的值傾向於不斷變化

比較右側: 用來做比較的表達式,它的值更傾向於常量

l if/else 語句塊的順序

首先處理正邏輯而不是負邏輯

再處理簡單的情況

最後處理有趣的或者是可疑的情況

l ?: 表達式, 只有在簡單的情況下使用

l 避免 do/while 循環

l 從函數中提前返回

l 最小化嵌套

l 減少循環內嵌套

2. 拆分超長表達式

l 用做解釋的變量



l 總結變量(用一個短很多的名字來代替一大塊代碼,這就是總結變量)

l 拆分巨大的語句

比如:



顯而易見,這段代碼邏輯很清晰,但是看著太複雜,下面改掉:



這樣做有很多好處:

- 避免輸入的錯誤。

- 縮短了行的寬度,更容易快速閱讀。

- 如果類名字改變了,只需要改變一個地方就行了。

3. 變量與可讀性

l 減少變量,即那些妨礙的變量。通過離開處理結果來消除「中間結果」的變量。

l 減少每個變量的作用域,越小越好。

l 只寫一次的變量更好,那些只設置一次值的變量(或者 const 、final 、常量)使得代碼更容易理解。

4. 抽取不相關的子問題

l 積極地發現並抽取不相關的子邏輯:

- 看看某個函數或代碼塊,問問自己:這段代碼的高層次的目標是什麼?

- 對於每一行代碼,問下:它是為了目標而寫的麼?

- 如果足夠的行數在解決不相關的子問題,試圖抽取代碼到獨立函數中。

l 純工具代碼(封裝共用的函數)

l 其他多用途代碼(比如頁面上數據邏輯代碼)

l 創建大量通用代碼(組件)

- 通用代碼很好,因為「完全地從項目的其他部分中解耦出來」。

l 項目專有的功能(私有組件)

l 簡化已有接口,按需重塑接口

5. 一次只做一件事

應該把代碼組織得一次只做一件事情。如何給代碼整理碎片,下圖演示了這個過程:



6. 把想法變成代碼

如果有好的想法,則可以實現為代碼,但需要注意以下幾點:

l 清楚地描述邏輯

l 可了解相關函數庫,以便減少代碼量

l 把這個方法應用於更大的問題

l 用自然語言描述解決方案

l 遞歸地使用這種方法

7. 少寫代碼

「最好讀的代碼就是沒有代碼」,在收到一個需求的時候,要質疑和拆分你的需求,用小的代碼庫,去替代大的代碼庫;刪除沒有用的代碼,簡化實現過程;熟悉你周邊的庫,了解最優庫;對於一些庫的重用,可以極大的節省時間。

總結

以上就是關於可讀性代碼的建議和實現方式,好的代碼不僅閱讀輕鬆,維護起來也是事半功倍。養成好的書寫處理習慣,會為我們的工作和學習帶來極大的便利。

文章來源: https://twgreatdaily.com/zh-tw/k2sComwBvvf6VcSZ_oFY.html