本文為 一旬一題寫作計劃 中 重構 專題內文章,讀完本篇大約需要4分鐘。
合理正確的命名簡直是編程時最常頭疼的問題之一(僅次于寫文檔),我的強迫癥同事每次寫新需求的代碼時候都要為此糾結半天。 我們會使用像下面這種,大家提到最多的,類似“格式規范”的命名規范: Google java編程風格指南中文版 Code Style for Contributors 這種規范規定了命名的格式,大大降低了代碼混亂度,但是對可讀性的貢獻卻還不夠。 好的代碼應該表達出自己的功能,望文知義是我們的追求。
/*能讀,不好讀*/houzi.food(b) // the money eats a banana/*望文知義,與自然語言(右側的注釋)很接近*/monkey.eat(banana) // the money eats a banana我們開發中可能60%的時間都花在命名和閱讀代碼上了,如何讓代碼更“可讀”(更有語義),是個值得花時間琢磨的問題。這篇文章將會介紹些讓命名更具語義的實踐。
命名必須傳遞足夠的信息。 通常,對象代表一個事物概念,我們使用名詞來命名。用名詞的復數或加上 List 、 Map 后綴來命名集合。函數都是用來做事情的,函數的名字應該由動詞開始。 于是我們建立了最基礎的規則:名詞命名對象,動詞命名函數。
我們編寫的大多數函數有個返回值,所以用動詞get開頭特別常見。對于簡單訪問對象屬性的方法,get還是蠻適合的,比如POJO和JavaBean的數據獲取方法。 但是多數情況下,get并不是一個好的選擇。想象有一個方法,它會連接到遠程服務器,搜索某個數據集,并將其排序后返回。我們可以把它叫做 getData,但這樣的命名就沒能提供足夠的信息,跟從本地獲取數據或者簡單訪問JavaBean沒有任何區別,讀者也無法猜測這個函數會做出些什么。如果換成fetchUserInfoAsync()之類的,函數的目的就一目了然了,讀者得到了函數做了更多的工作來提取數據的暗示。 我們可以提煉出一條新規則,即時直接訪問數據時用get,其他更復雜的情況應當另選更精確的動詞。比如做數學運算得出一個返回值的函數,calculate 會比 get 合適。
試下給下面的函數選個動詞。
Item getItem(Item match) { for(Item temp : itemList){ if(temp.values == match.values){ return temp; } }}看看這個函數干了什么,不是簡單地獲取某個數據,它在集合中搜索某個符合條件的元素并返回。searchItem或者findItem都是容易想到而且很不錯的選擇。試下描述函數的功能,從中摘取動詞,就是這么簡單。
有的人喜歡用do命名,仔細想想,每個函數都有do一些事情,do 幾乎不能提供任何有用信息。類似的詞語還有handle, perform, return。
Boolean返回值函數最適合用 is, are, was, were開頭,或者搭配情態動詞。
情態動詞(Modal verbs)本身有一定的詞義,表示語氣的單詞。但是不能獨立作謂語,只能和動詞原形一起構成謂語。情態動詞用在行為動詞前,表示說話人對這一動作或狀態的看法或主觀設想。
也就是can, could, may, might, must, shall, should, will 和 would,這些詞隱含了假設當前條件為真的反問信息。比如Button.isEnabled(),User.canaccess()。
Java語言中,方法是某個類里面定義的一個函數,也就是方法跟類是有綁定關系、在類或者對象的上下文中運行。所以有時候函數名中沒必要再描述主語。比如一個保存信息的方法,可以叫做saveMessage();假如這是Message類的一個方法,就可以簡化為save()。你可以對比感受下Message.save()和Message.saveMessage()。
函數的簽名本身就告訴了讀者有什么參數,再在方法名中描述就多余了。findUserByUserIdAndToken(String userId, String token) 可以簡化成 findUser(String userId, String token)。
雖然不是必要的,但如果遵循這種語義規范(況且也不難),能讓我們的代碼很清楚地表達出它的關鍵邏輯。重構過代碼的同學應該明白這種代碼的自描述性有多重要。
任何一個傻瓜都能寫出計算機可以理解的代碼,唯有寫出人類容易理解的代碼,才是優秀的程序員。 ——《重構:改善既有代碼的設計》
錯誤代碼的影響力是有限的,bug很快會遁形;但能正確執行的無法理解的混亂代碼卻會造成長遠的負面影響。多花一丟丟時間去提升代碼的清晰度,后面的開發才會更愉悅。
參考資料與擴展閱讀
Semantic method naming
編寫「可讀」代碼的實踐
Google Java編程風格指南中文版
Code Style for Contributors
新聞熱點
疑難解答