早在2013年,國外有個程序員作了一個有意思的投票統計(原始連接請見:《程序員:你認爲最難作的事情是什麼?》),該投票是讓程序員從如下幾個選項中選出平時在工做中本身認爲最難作的事情:html
也許在你們的印象中,撰寫設計文檔和在別人寫的代碼基礎上作改造應該是最難的事情。可是最終的投票結果確讓你們意想不到,此次投票一塊兒有4522名程序員參與了投票,排在第一位的是給函數、變量命名:java
大概一半的人投票給了給函數、變量命名,從此次投票結果咱們足能夠看出:給函數、變量命名雖然是一件再普通不過的事情,可是要想把這件事作好絕非易事。那麼今天,咱們就來聊一聊如何給函數取一個好的名字。如下是本文大綱目錄:程序員
一.常見的函數命名風格緩存
二.函數命名的最高境界bash
三.函數命名最佳實踐session
如有不正之處請多多諒解,並歡迎批評指正。app
請尊重做者勞動成果,轉載請標明原文連接:函數
https://www.cnblogs.com/dolphin0520/p/10567879.html測試
目前來講,最多見的函數命名主要有兩種風格:駝峯命名和帕斯卡命名。fetch
public void setUserName(String userName);複製代碼
public void SetUserName(String userName);複製代碼
兩種命名風格都是ok的,但要保證一點,對於一個團隊或者一個項目,須要根據語言自己的推薦命名方式作好約定。好比java通常都採起駝峯命名,C#採起帕斯卡命名。
咱們一般說:天下武功,惟快不破。那麼對於函數命名來講最高境界是什麼呢?我認爲是:見字如面,顧名思義,就是看到函數的名字就知道這個函數具體作了哪些事情。
好比上面的函數:
public void setUserName(String userName);複製代碼
可是下面這個函數命名就不是一個好的命名:
public String addCharacter(String originString, char ch);複製代碼
這個函數,一咋看,還不錯,從函數字面意思看是給某個字符串添加一個字符。可是究竟是在原有字符串首部添加,仍是在原有字符串末尾追加呢?亦或是在某個固定位置插入呢?從函數名字徹底看不出來這個函數的真正意圖,只能繼續往下讀這個函數的具體實現才知道。
而下面這幾個名字就比上面要好得多:
public String appendCharacter(String originString, char ch); // 追加到末尾
public String insertCharacter(String originString, char ch, int insertPosition); // 插入指定位置複製代碼
1)要領1:動詞選取要精準
一般來講,動詞決定了一個函數要採起什麼"動做"。動詞取的好,一個函數名字已經成功了80%。
經常使用動詞表:
類別 |
單詞 |
---|---|
添加/插入/建立/初始化/加載 |
add、append、insert、create、initialize、load |
刪除/銷燬 |
delete、remove、destroy、drop |
打開/開始/啓動 |
open、start |
關閉/中止 |
close、stop |
獲取/讀取/查找/查詢 |
get、fetch、acquire、read、search、find、query |
設置/重置/放入/寫入/釋放/刷新 |
set、reset、put、write、release、refresh |
發送/推送 |
send、push |
接收/拉取 |
receive、pull |
提交/撤銷/取消 |
submit、cancel |
收集/採集/選取/選擇 |
collect、pick、select |
提取/解析 |
sub、extract、parse |
編碼/解碼 |
encode、decode |
填充/打包/壓縮 |
fill、pack、compress |
清空/拆包/解壓 |
flush、clear、unpack、decompress |
增長/減小 |
increase、decrease、reduce |
分隔/拼接 |
split、join、concat |
過濾/校驗/檢測 |
filter、valid、check |
2)要領2:名詞使用領域詞彙
動詞決定了函數的具體動做,而名詞決定了函數具體的操做對象,對於名詞,儘可能使用領域詞彙,不要使用生僻或者你們不多使用的詞語。
舉個例子:集合的容量一般用capacity、集合實際元素個數用size、字符串長度用length,這種就遵循你們的使用習慣,不要用size去形如字符串的長度。
再好比,假如使用到建造者模式,那麼一般會用build做爲函數名字,這個時候就不要另闢蹊徑,用create來做爲函數名字,使用你們約定俗成的命名習慣更容易讓你的代碼被別人讀懂。
經常使用名詞表:
類別 |
單詞 |
---|---|
容量/大小/長度 |
capacity、size、length |
實例/上下文 |
instance、context |
配置 |
config、settings |
頭部/前面/前一個/第一個 |
header、front、previous、first |
尾部/後面/後一個/最後一個 |
tail、back、next、last |
區間/區域/某一部分/範圍/規模 |
range、interval、region、area、section、scope、scale |
緩存/緩衝/會話 |
cache、buffer、session |
本地/局部/全局 |
local、global |
成員/元素 |
member、element |
菜單/列表 |
menu、list |
源/目標 |
source、destination、target |
3)要領3:函數取名最忌諱"名存實亡"
函數取名最忌諱的是"名存實亡",舉個例子,假若有個Cache類,裏面有個函數判斷key是否過時:
public boolean isExpired(String key) {
// 當前時間戳
long curTimestamp = DateUtils.nowUnixTime();
// 獲取key的存入時間戳
long storeTimestamp = getStoreTimestamp(key);
if (curTimestamp - storeTimestamp > MAX_EXPIRE_SECONDS) {
// 注意這個地方的delete是個隱藏邏輯
delete(key);
return true;
}
return false;
}
複製代碼
上面這個函數從函數字面意思看是判斷key是否過時,可是!!它竟然在函數裏面隱藏了一段特殊邏輯:若是過時則刪除掉key。這個就是典型的"名存實亡",這個是最忌諱的,會給後續的開發人員留下"巨坑"。
有兩種方式去優化這段代碼:
public boolean isExpired(String key) {
// 當前時間戳
long curTimestamp = DateUtils.nowUnixTime();
// 獲取key的存入時間戳
long storeTimestamp = getStoreTimestamp(key);
if (curTimestamp - storeTimestamp > MAX_EXPIRE_SECONDS) {
return true;
}
return false;
}複製代碼
public int deleteIfExpired(String key) {
// 當前時間戳
long curTimestamp = DateUtils.nowUnixTime();
// 獲取key的存入時間戳
long storeTimestamp = getStoreTimestamp(key);
if (curTimestamp - storeTimestamp > MAX_EXPIRE_SECONDS) {
return delete(key);
}
return 0;
}複製代碼
4)要領4:多查詢條件的函數名字謹慎使用介詞by
咱們平時在寫查詢接口時,假若有多個查詢參數怎麼辦?每一個經過by一塊兒鏈接依賴?No!這絕對不是明智的方式。假如一開始產品的需求是經過學生姓名查詢學生信息,寫出來的多是這樣的函數:
public List<Student> getByName(String name);
複製代碼
而後忽然又有一天產品提出了新的需求,但願同時能夠經過姓名和電話號碼來查詢學生信息,那麼函數可能變成這樣了:
public List<Student> getByNameAndMobile(String name, String mobile);
複製代碼
接着,沒過多久,產品又但願根據學生年齡來查詢學生信息,那麼函數可能變成這樣了:
public List<Student> getByNameAndMobileAndAge(String name, String mobile, int age);
複製代碼
若是這樣來給函數命名,那麼你的噩夢大門即將打開。
一般比較好的作法是:
若是是經過主鍵id來查詢,那麼能夠經過by來鏈接查詢信息,好比:
public Student getByStudentId(long studentId);複製代碼
若是是經過其餘屬性來查詢,而且將來會存在多個組合查詢的可能性,建議進行封裝,好比:
public List<Student> getStudents(StudentSearchParam searchParam);
複製代碼
最後,建議你們平時在寫代碼過程當中,不要怕在函數命名上耗費時間,一個好的函數命名在後期會大大減小你代碼重構的成本,爭取對函數命名作到"見字如面"~