如何編寫簡潔的程式碼?
引言
學習來源:《Clean Code》 [美] Robert C.Martin。
這是本人的學習筆記,現在大部分寫程式碼的時候已經對這些規則和概念有了一個清晰的認識,希望大家有機會也能看一看《Clean Code》這本書,總結出屬於自己需要的規則。
一.有意義的命名
1.名副其實
int d;//消逝的時間,以日計 int elapsedTimeInDays; 複製程式碼
2.避免誤導
別用accountList來指稱一組賬號,除非它真的是List型別。提防使用不同之處較小的名稱。誤導性名稱最可怕的例子,是用小寫字母“l”和大寫字母“O”作為變數名。因為他們看起來實在太像數字“零”和“壹”。如以下程式碼:
int a=l; if(O==l) a=O1; else l=01;複製程式碼
3.做有意義的區分
廢話是另一種沒意義的區分。例如你有一個Product類和一個ProductInfo類,這兩個名稱雖然不同,意思卻毫無區別。
4.使用讀的出來的名稱
像生成時間戳 這個變數應該是 generationTimestamp 而不是 genymdhms .
5.使用可搜尋的名稱
儘量避免使用單字母和數字作為常量名稱,因為它們通常很難在一大段程式碼中被準確的搜尋出來。作者認為 單字母名稱 僅用於短方法中的本地變數。名稱長短應與其作用域大小相對應。
6.避免使用編碼
把型別和作用域編進名稱裡面,徒然增加了解碼的負擔。典型的如:
-
ofollow,noindex">匈牙利語標記法
-
成員字首(沒必要使用字首來標明成員變數,應當把類和函式做的足夠小,消除對成員字首的需要)如下程式碼:
public class Part{ String description; void setDescription(String description){ this.description=description; } }複製程式碼
7.避免思維對映
不要讓讀者在腦中把你的名稱翻譯為他們熟知的名稱。這種問題經常出現在選擇是使用問題領域術語還是解決方案術語時。
8.類名
類名應該是名詞或名詞短語,例如 Customer、WikiPage、Account 和 AddressParser,類名不應當是動詞,例如 Manager、Processor、Data或者Info。
9.方法名
方法名應當是動詞或動詞短語,如 postPayment、deletePage 或save。
10.每個概念對應一個詞
給每個抽象概念選一個詞,並且一以貫之。例如,使用fetch、retrieve和 get 來給在多個類中的同種方法命名。
11.使用解決方案領域名稱
記住,只有程式員才會讀你的程式碼。所以,儘管使用那些計算機科學術語、演算法名、模式名、數學術語吧。依據問題所涉領域來命名可不算是聰明的做法。
12.使用源自所涉問題領域的名稱
如果不能使用解決方案領域名稱來命名,就採用所涉問題領域的名稱,至少負責維護程式碼的程式設計師可以去請教該領域專家。
13.新增有意義的語境
讓你的程式碼讀起來是連貫的,是在同一語境的。能明確的知道,這些類,函式是某個結構的一部分。這需要通過良好命名的類,函式和名稱空間來形成有意義的語境。
14.不要新增沒用的語境
只要短名稱足夠清楚,就比長名稱好,不要一昧的追求長名稱,從而造成很多不必要的語境。給人以困擾。
二.函式
1.第一規則:短小
if語句、else語句、while語句等,其中的程式碼塊應該只有一行。函式的縮排層級不應該多於一層或兩層。
2.只做一件事
函式應該只做一件事,做好這一件事。
3.每個函式一個抽象層級
自頂向下讀程式碼:向下原則。
4.使用描述性的名稱
長而具有描述性的名稱,要比短而令人費解的名稱好。
長而具有描述性的名稱,要比描述性的長註釋好。
5.函式引數
引數數量儘可能的少,最好的是零引數函式,其次是一(單引數函式),再次是二(雙引數函式),應儘量避免三(三引數函式)。
5.1 標識引數
應當儘量避免標識引數,避免向函式傳入布林值。
5.2 三元函式
寫三元函式之前一定要深思熟慮,是否有必須寫三個引數的必要性。
5.3 引數物件
如果函式需要兩個,三個或三個以上的引數,就說明其中一些引數應該封裝為類了。
5.4 動詞與關鍵字
對於一元函式,函式和引數應當形成一種非常良好的動詞/名詞對形式。
例如:write(name),或者更好的名稱:writeField(name)。 例如:assertEqual改成assertExpectedEqualsActual(expected,actual)。 複製程式碼
5.5 錯誤處理
-
使用異常代替返回錯誤碼
-
抽離Try / Catch 程式碼塊
-
函式應該只做一件事,錯誤處理就是一件事。因此,錯誤處理的函式不該做其他事。
5.6 別重複自己
不要編寫重複性的函式。
5.7 結構化程式設計
Edsger Dijkstra的結構化程式設計規則。
三.註釋
關於註釋的問題,首先我們應該明確的是能用程式碼闡述的就不要寫註釋,避免誤導。也就是程式碼可讀性非常高,幾乎可以不用註釋,這需要良好的命名習慣來形成。另外,註釋並不能夠美化你寫的糟糕的程式碼。與其有時間寫註釋,不如花時間優化你的程式碼。如果我們在必須寫註釋的情況下,需要明確的知道自己想要寫的是好註釋還是壞註釋。
好註釋
-
法律資訊(例如版權及著作宣告)
-
提供資訊的註釋(例如解釋某個抽象方法的返回值,當然更好的是在方法名中體現,從而省略註釋)
-
對意圖的解釋(對某些看起來與常理不符合的程式碼解釋你的意圖,如 sleep 函式)
-
警示(警告執行後會出現某些後果的程式碼)
-
TODO 註釋(告訴其他人這裡還有個未完成的工作,以及將來完成後應該是怎麼樣的)
法律資訊(例如版權及著作宣告)
提供資訊的註釋(例如解釋某個抽象方法的返回值,當然更好的是在方法名中體現,從而省略註釋)
對意圖的解釋(對某些看起來與常理不符合的程式碼解釋你的意圖,如 sleep 函式)
警示(警告執行後會出現某些後果的程式碼)
TODO 註釋(告訴其他人這裡還有個未完成的工作,以及將來完成後應該是怎麼樣的)
壞註釋
-
多餘的註釋
-
日誌式註釋(記錄每次的修改日誌,目前在原始碼管理非常完善的今天,日誌式註釋應該被廢棄了)
-
註釋掉的程式碼(不要直接註釋掉程式碼!無用則請刪除,註釋而不是刪除會讓其他人誤以為這段程式碼仍有用處)
-
歸屬與署名(通過原始碼管理,署名也是可以被廢棄的)
-
括號後面的註釋(不要在括號後面寫註釋)
-
資訊過多(別在註釋中新增無關緊要的資訊)
多餘的註釋
日誌式註釋(記錄每次的修改日誌,目前在原始碼管理非常完善的今天,日誌式註釋應該被廢棄了)
註釋掉的程式碼(不要直接註釋掉程式碼!無用則請刪除,註釋而不是刪除會讓其他人誤以為這段程式碼仍有用處)
歸屬與署名(通過原始碼管理,署名也是可以被廢棄的)
括號後面的註釋(不要在括號後面寫註釋)
資訊過多(別在註釋中新增無關緊要的資訊)