也許有多少專業Java程序員,就有多少種對于編寫優良Java代碼的答案!
以下可能是大多數專業Java程序員都贊同、也愿意執行的八點規則:
1) 保持類最小
還有什么比擁有較少的類更壞的事情嗎?可能不會再有了。當然,最好還是有滿足自己需要的類。
一般來說,一個帶有大量方法的類總是具有一些不屬于這里的方法,因為這個龐大的對象所做的事情太多了。如果您有一個帶有 100 個方法的對象,就應該好好想想,這個對象是否應該拆成多個對象。大類通常在大學里大行其道。Java 代碼與之一樣。
2) 保持方法最小
小方法就與小類一樣可取,并且原因也類似。
很多有經驗的 OO 程序員對 Java 語言具有的苦惱之一就是,它提供大量的 OO 能力,但是卻沒有教他們如何做好 OO。換句話說,它給了他們很多繩子去捆綁自己(盡管至少沒有 C++ 給他們的多)。能看到這一點的一個常見地方是 main()
方法離得很遠的類,或者一個單個的名叫 doIt()
的方法。僅僅因為能夠 將所有的代碼放在類中的單個方法中,并不意味著就應該 如此。Java 語言比很多其他 OO 語言具有更多的語法糖,所以一定的羅嗦是必要的,但是不要過了度。
思考一下這些超長的方法。滾動十屏代碼去了解代碼所做的工作是很艱難的。該方法做什么工作?您需要泡上一杯大大的咖啡花幾個小時去研究才能知道。一個小的,甚至微小的方法是一個容易看懂的代碼塊。運行時效率不是要具有小方法的原因,可讀性才是真正的目標。這將使得代碼更加容易維護,并且在需要添加功能時更加容易更改。
將每個方法局限于執行一項工作。
3) 給方法取好名稱
本要求很簡單,只需要花上一點時間想出一個具有描述性的方法名,足夠明了但不過長。
這一技巧很簡單,也許在小規模的代碼行中是微不足道的,但是當代碼變得越來越復雜時,它就會顯露出驚人的威力。
4) 保持類的數量最少
XP 中關于簡單設計的其中一個指導方針是,用盡可能少的類完成一個目標。如果您需要另一個類,盡管添加就是了。如果另一個類將使得代碼更簡單或者簡化您的意圖表達,那么就添加這個類吧。但是沒有理由只是為了具有而具有類。當然,通常項目早期比結束時具有的類要少,但是一般將代碼重構成更多的類比組合類更容易。如果您有一個具有大量方法的類,那么分析一下,看是否有另一個對象陷入在其中,正在等待出去。如果有的話,就創建一個新的對象。
在我經歷的幾乎所有 Java 項目上,沒有人害怕創建類,但是我們也總是試圖在不降低意圖清晰度的情況下,減少類的數量。
5) 保持注釋的數據最少
我過去常常在代碼中編寫很多的注釋,讀起來就像一本書。后來我變得聰明一些了。
每一個計算機科學程序、每一本編程書籍和我知道的很多程序員,都要您給代碼編寫注釋。在有些情況下,注釋是有幫助的。在許多情況下,注釋使得代碼維護更加困難。想想您更改代碼時必須做什么。有注釋嗎?如果有的話,您最好更改注釋,否則它會可怕地過期,甚至隨著時間的推移,根本就不再能夠描述代碼。依我的經驗,幾乎會使維護時間加倍。
我的經驗法則是:如果代碼太難閱讀和理解而需要注釋,我就需要使它足夠清晰,從而不需要注釋。代碼可能會太長,或者做太多的事情。如果這樣的話,我就簡化它。代碼可能太隱晦。如果這樣的話,我就添加助手方法,使之清晰。實際上,在與同一團隊的其他成員一起進行 Java 編程的三年當中,我所編寫的注釋屈指可數。保持代碼清晰!如果您需要系統或者某個特定組件的全景描述,就編寫一個簡短的注釋來描述。
羅嗦的注釋一般比較難維護,通常不及一個小的、編寫良好的方法那么好地表達意圖,并且很快就會過期。根本不要過分依賴注釋。
6) 使用一致的風格
編碼風格實際上是您的環境中必然的并且可接受的東西。我甚至不知道哪一種風格可以稱為“典型的”。這通常是個人品味問題。
有時候,對于同一段代碼,可能有好幾種排列方法,實際上沒有絕對的“對”與“錯”。實際項目過程中,應該進行協商,挑選出一種來,然后一直堅持用這一種。惟一絕對的風格規則是一致性。如果一個項目上的每個人都用不同的風格,那么閱讀代碼將變得很困難。挑選一種風格并且不要改變。
7) 避免switch
一些 Java 程序員對 switch
語句情有獨鐘。我曾經認為它們很好,但是后來我認識到了,一個 switch
實際上就是幾個 if
,并且通常意味著條件邏輯出現在代碼中的多個地方。這是代碼重復,是應該禁忌的。為什么?因為在多處具有相同的代碼使得代碼比較難更改。如果我在三處具有相同的 switch
,并且想要更改對某個 case 的處理,我就得在三處更改代碼。
現在,如果您可以重構具有單個 switch
語句的代碼,那會怎么樣呢?很好!我不相信使用它有什么壞處。在有些情況下,它比嵌套的 if
更清晰。但是如果您看到它出現在很多地方,就有了應該解決的問題了。防止這一問題的一個容易的方法是,避免 switch
,除非它對于該工作是最佳的工具。依我的經驗,它很少是最佳的。
8) 是public的
我把最具爭議的建議放在最后。做一下深呼吸。
我相信您會反對讓所有的方法都是 public
的。實例變量應該是 protected
的。
當然,許多專業程序員會害怕這種想法,因為如果任何東西都是公共的,那么任何人都可以更改它,也許會以未授權的方式更改。在任何東西都是公共可訪問的世界中,您就不得不依賴于程序員紀律,以確保人們在其不應該訪問時不會訪問其不應該訪問的東西。但是在編程生活當中,很少有什么事情比想要訪問一個不可見的變量或方法更受挫的了。如果您對代碼中您設想其他人不應該訪問的東西限制訪問,您就是在設想自己無所不知。這在大多數時候是一個危險的假設。
當使用其他人的代碼時,這種受挫感會經常出現。您會看到一個方法剛好做您想要做的工作,但是它不是公共可訪問的。有時,這有一個很好的原因,并且使得限制可訪問性有意義。但是有時,不 public
的惟一原因是,編寫代碼的人這樣想“沒有人需要訪問該代碼”,或者他們這樣想“沒有人應該訪問該代碼,因為……”,于是他們并沒有很好的理由。許多時候,人們使用 private
是因為它可用。不要這樣做。
使方法是 public
的,變量是 protected
的,直到您有一個很好的理由限制訪問。
現在您知道了如何創建優良的 Java 代碼,以及如何保持它優良。
關于該主題,業界最好的書籍是 Martin Fowler 編著的 Refactoring(參見 參考資料 中的鏈接)。它讀起來甚至很有趣。重構(refactoring) 的意思是在不改變代碼結果的情況下,更改現有代碼的設計。Fowler 談論了請求重構的“代碼氣味”,并且詳細介紹了用于改變“代碼氣味”的各種技巧(或者“重構”)。依我的觀點,重構和編寫一次通過測試的代碼的能力(參閱 參考資料)是新手程序員要學習的最重要的技能。如果每個人都擅長于這兩點,那將徹底改變行業當前的局面。如果您 擅長于這兩點,就會比較容易找到工作,因為您能比其他人產生更好的結果。
編寫 Java 代碼相當簡單。編寫優良的 Java 代碼則是一門手藝。傾力成為一個手藝人。