命名規範
命名長度
命名的原則以準確達意為目標,其長度以遵循此原則為主,並且是越短越好。
- 對於公認、熟知的詞,可以在專案內部統一成縮寫
- 對於作用域較小的變數,可以使用較短的命名
- 對於作用域較大的變數,推薦使用可達意的較長的命名
命名上下文
命名時可以根據上下文來簡化命名,如在 User 類中,就不需要對類中的成員變數新增 user
字首,而是直接命名如 name
、password
等名稱。
在使用時,開發者也可以藉助上下文明確變數的含義。
可讀性
可讀性指的是不使用特別生僻、難發音的英文單詞來命名,同時也不要使用一些無意義、隨意搭配的單詞。
可搜尋性
命名可搜尋性指的是,使用 IDE 開發的時候,可以很方便地使用“關鍵詞聯想”功能快速補全。
這個原則指的是,最好能在專案、團隊內部統一命名方式,如都使用 selectXXX
表示查詢,而不是既有 selectXXX
,也有 findXXX
或 queryXXX
等多種命名方式表示查詢。
介面、抽象類
對於介面的命名,通常有兩種比較常見的方式:一種是介面加字首 I
表示 Interface,如 IUserService
;另一種是實現類加字尾 Impl
表示 implements,如 UserServiceImpl
。
對於抽象類的命名,也有兩種常見的方式:一種是帶上字首 Abstract
表示抽象類,如 AbstractConfig
;另一種是不帶字首。
無論是介面還是抽象類,選擇哪個命名方式都可以,最重要的是能在專案內部統一。
註釋規範
註釋內容
註釋的目的是讓程式碼更容易看懂。
註釋的內容主要是包括三個方面:做什麼、為什麼做、怎麼做。對於複雜的介面或類,還需要補充“如何用”。
註釋多少
註釋本身有一定的維護成本,並非越多越好。
類和函式一定要寫註釋,而且要寫得儘可能全面、詳細,函式內部的註釋要相對少一些,一般可以透過好的命名、提煉函式、解釋性變數、總結性註釋等方式來提高程式碼可讀性。
程式碼風格
類和函式的行數
對於函式程式碼行數的最大限制,網上有一種說法:最好不要超過一個螢幕的垂直高度。
對於類的程式碼行數的最大限制,有一個間接的判斷標準:
- 當一個類的程式碼讀起來比較困難
- 實現某個功能時不知道該用哪個函式
- 想用哪個函式的時候需要找很久
- 只用到一個小功能的時候要引入整個類
一行程式碼的長度
總體遵循一個原則:一行程式碼最長不能超過 IDE 顯示的寬度。
需要滾動滑鼠才能檢視一行的全部程式碼,顯然不利於程式碼的閱讀;但是太小的限制也會導致很多稍長點的語句被折成兩行。
分隔單元塊
對於比較長的函式,如果邏輯上可以分為幾個獨立的程式碼塊,但是又不方便將這些獨立的程式碼塊抽取成小函式的時候,可以使用總結性註釋的方式分隔程式碼塊。
除此之外,還可以透過使用空行分隔程式碼塊。如類的成員變數和函式之間、靜態成員變數和普通成員變數之間、各函式之間、甚至是各成員變數之間。
類成員的排列順序
在 Google Java 程式設計規範中,依賴類按照字母序從小到大排列、類中先寫成員變數後寫函式、成員變數之間或函式之間先寫靜態成員變數或函式(按照作用域大小依次排列)。
常用技巧
善於提煉函式
對於邏輯比較複雜的程式碼,通常是建議提煉出類或者函式,但也避擴音煉出的函式只包含兩三行程式碼,以增加閱讀成本。
避免函式引數過多
通常函式的引數超過 5 個時候就會影響到程式碼的可讀性,使用起來也不方便。
出現函式引數較多的情況,通常有兩個解決辦法:根據單一職責原則拆分成多個函式;將函式的引數封裝成物件。
勿用函式引數控制邏輯
切勿在函式內部根據函式的引數來控制內部邏輯,如根據 isVip = true
時走 VIP 的邏輯、isVip = false
走非 VIP 的邏輯。
針對於這樣情況,通常是根據需求將其拆分成多個函式,拆分之後的函式職責更明確。
函式設計要職責單一
不只是針對類、模組而言,對於函式的設計,更要滿足單一職責原則。
移除過深的巢狀
程式碼巢狀最好不超過兩層,超過兩層之後就要思考一下是否可以減少巢狀,以避免難以理解和程式碼縮排過多。
解決程式碼巢狀過深的方法有以下幾種思路:
- 去掉多餘的
if
或者else
語句 - 使用程式語言提供的
continue
、break
、return
關鍵字提前退出巢狀 - 調整執行順序來減少巢狀
- 將部分巢狀的邏輯封裝成函式呼叫,以此來減少巢狀
- 使用多型來替代
if-else
、switch-case
條件判斷
使用解釋性變數
使用解釋性變數可以提高程式碼的可讀性,常見的情況有以下幾種:
- 使用常量取代魔法數字
- 使用解釋性變數來解釋複雜表示式
函式錯誤返回
函式的執行結果可以分為兩類:正確情況下輸出的預期結果,異常(出錯)情況下輸出的非預期結果。
在異常情況下,函式返回的資料型別非常靈活,可以針對不同的場景和特點選擇不同的返回值。
返回錯誤碼
C 語言沒有異常這樣的語法機制,返回錯誤碼是最常見的出錯處理方式。
而 Java、Python 等比較新的程式語言,大部分情況下,都用異常來處理函式出錯的情況,極少會用到錯誤碼。
返回 NULL 值
在多數程式語言中,使用 NULL
值表示“不存在”這種語義。
對於查詢函式來說,資料不存在並非一種異常情況,是一種正常行為,所以返回表示“不存在”語義的 NULL
值比返回異常更加合理。
返回空物件
返回 NULL
值有各種弊端,對此有一個比較經典的應對策略,那就是應用空物件設計模式。
當函式返回的資料型別是字串型別或者集合型別的時候,可以用空字串或空集合替代 NULL
值,來表示不存在的情況。
丟擲異常物件
最常用的函式出錯處理方式是丟擲異常。異常可以將正常邏輯和異常邏輯的處理分離開,這樣的程式碼可讀性會更好。
對於丟擲的異常物件,通常有以下幾種處理方式:
- 直接吞掉,如在捕捉之後只記錄日誌,不做任何處理
- 原封不動的重新丟擲,如在呼叫的函式外部重新丟擲相同的異常
- 包裝新的異常重新丟擲,如在捕捉之後丟擲另一個的異常