Java编码规范
先借編碼規范之名,行吐槽之實,抱歉。
寫干凈整潔的代碼
閱讀代碼,眼緣很重要。代碼是程序員的臉,保持干凈整潔。
建議使用eclipse默認的就行,Ctrl+Shift+F。項目內部格式化風格一定要統一,否則svn很難track。鑒于Java開發庫以及流行的開源框架都用Block起始大括號不換行風格,Google也如此規范,統一為這種風格。
純粹是美觀的考量。Google要求import語句里面不允許出現*,更不能引入沒有用到的代碼。Eclipse里面的快捷鍵是Ctrl+Shift+O,這個鍵還能幫忙導入用到的類。
修改代碼的時候,有些同學會把老的沒有用的代碼注釋起來,像寶貝一樣生怕弄丟,日積月累,注釋的代碼比有用的代碼還多幾倍,很難閱讀和維護。請刪掉它,備份的問題放心的交給SVN或Git。
TODO Auto-generated method stud等等之流的,請刪掉,不解釋。
空行的唯一作用是分割邏輯代碼,是閱讀時候大腦的一個休息區。但是空行又是昂貴的,編輯器一頁代碼200行以內,使用空行太過奢侈的話,我就光閱讀空行了。Google不鼓勵多個空行,依我的觀點,絕對不能有兩個相聯的空行,原因簡單,浪費可恥,眼睛跳躍也累。當然也反對幾十行代碼沒有一個空行,大腦得累死。總之,優美的代碼一定合理的利用了空行,空行都用不好寫不出優美的代碼。
每一個Warning背后都有一個故事,泛型,未被使用的Class引用,未被使用的private方法,未被使用的field,class cast,序列化等等。搞懂一個Warning背后的故事,優雅的解決掉一個Warning,你就向高手邁進了一步。如果實在是搞不定,注釋SuppressWarning能夠暴力的幫助你。
高效運用注釋
有人說注釋和代碼一樣重要,我不太認同。簡單優雅的代碼比注釋更直接易懂,注釋會騙人,代碼不會,注釋不正確比沒有注釋糟糕很多很多,一大堆無用的注釋浪費空間,浪費腦力,不如沒有注釋。一段關鍵的算法,一個場景的特殊處理,用簡短的注釋解釋思路,這里注釋對于后來的維護人員來說,比代碼更加重要。接口的注釋是使用接口人員的說明文檔,對他們來說也比代碼重要。如果一段代碼需要你很多很多的注釋才能解釋清楚,那么請重寫那段代碼,直到簡短注釋甚至無需注釋。
包括Interface、非Java Bean的public方法以及工具類里面的public static方法。關注做什么(不是怎么做),輸入輸出,特殊情況處理(比如null或不合法參數),異常情況。這種為塊級(Block)注釋,一般用/** comments */格式。
特殊的算法體現的是作者當時解決問題的思路和算法,具有業務上或者算法上的特殊性,需要備注一下,以防忘記或者其他維護同事難以理解。通常用單行注釋即可,特別長的用/* comments */ 格式。
主要是幫助閱讀代碼的時候幫助理解。格式和第二條相同。
關于名字,請在Class的注釋里面加一個@author yourname。閱讀代碼的時候,只有遇到很爛或者很優雅的代碼,我才會去關注作者是誰,通過Class里面的@Author和SVN抑或Git,很輕松的就知道代碼出自誰的手。關注代碼的時候實在是沒有興趣思考你是誰。至于Ticket單號,提交代碼的時候注釋就足夠了,項目由代碼構成,而非Ticket,需要追蹤的時候SVN或Git都能夠輕松地幫忙搞定。
可以理解為方法內部慎用多行注釋。方法內部應該Focus在代碼的實現上,而不是實現的思路,思路請移到方法的注釋里面。方法里面的注釋應該關注在一些特殊情況處理,程序邏輯的跳轉上面,一般單行注釋足夠勝任。如果方法內部要用大段的注釋,還是那句話,請重寫。
命名簡潔一致
命名規范是代碼規范的重要一環。總的原則是遵循慣例,簡潔,團隊甚至個人命名保持一致。
項目名,包名,類名,變量名,參數名都用名詞命名,方法用動詞開始命名。
包名全小寫,每一個文件夾用一個名詞命名,注意有且一個詞,且長度盡量短一些。類名標準的HelloWorld格式,有人問FBIHelloWorld好呢還是FbiHelloWorld好,我看著后者順眼,你呢?普通變量,方法名,參數名一律helloWorld,hWorld可不可以?反射的時候有問題,也不好看,建議每一個單詞至少兩個字母。Final變量HELLO_WORLD,同樣不解釋。
特別強調,簡潔不是說鼓勵簡寫,相反簡寫要慎用,最好團隊內部達成共識。我說的簡潔是指找那么一個貼切、簡短的詞或詞組來命名。
A君FBIHelloWorld,B君FbiHelloWorld,C君hWorld,甚至A君混合兩種風格,整個項目會顯得混亂,難以理解和維護。
理解Java幾個基本的概念
一些Java的基本概念一定要吃透,否則很容易犯低級錯誤。
Exception
麻煩統計一下你們項目里面處理異常,簡單地e.printStackTrace()個數,少不能說明你們項目代碼質量一定很高,但太多了一定意味著你們的代碼質量不咋地,如果這些爛代碼由很多人提交,那更是悲劇。e.printStackTrace()只是把Exception toString(),然后輸出到System.err,開發的時候控制臺還能顯示一下,生產環境到哪里去找。我覺得簡單e.printStackTrace()和try catch之后什么都不干一樣惡劣。想看報錯信息?借助Log4j或者Logback記日志吧,既能開發的時候控制臺看到,也能在生產時記錄到文件系統。
- 何時拋出異常
不正常的場景出現,當前程序決定罷工,并可選擇地攜帶一些錯誤信息告知調用者,小心,異常。如果你的程序就是最后一環,拜托,別拋了,選擇更優雅的方式吧。 - 何時處理異常
確定你可以處理那樣的異常,并且決定catch之后如何繼續下面的操作。catch之后記錄日志是標配。如果你開發GUI,你就是最后的消費者,必須處理異常。
Transaction
如果你開發的系統要求數據的完整性和準確性,請花些時間好好吃透Transaction。有一個業務Service A,分為兩個子Service A1, A2。如果分別調用A1和A2,并放到兩個Transaction里面,如果A1執行成功,A2失敗并Rollback,請問發生了什么?Service的粒度劃分和Transaction的使用非常的重要。
Thread
不懂或者半懂不懂千萬別用多線程,要用就去好好的了解一下它。依我的理解,多線程僅用在兩個地方,性能提升和響應式(Responsive)的GUI界面。
Access
兩個字,要明確。類,構造函數,屬性,方法的訪問權限要明確。public, protected,package,private,四個級別,了解不難,用好要功力。有的不喜歡明確定義訪問級別的朋友會辯解說,我看JDK里面有的屬性或者方法就沒有申明權限嘛,JDK的開發工程師也懶。哈哈,往后看看,大多會特別的注釋說是package級別的,如果package關鍵字能夠用來定義package權限,他們估計早用了,何必還多寫那么些冗余的注釋。interface里面不用明確申明public,因為默認就是public的,而且只能是public的。程序員太懶惰不好,太勤快了也不好,難當。
尋求更好的解決辦法(Better Solution)
項目經理A或業務達人B跑過來,某客戶有一個新的需求,請幫忙如此如此改一下系統,如此如此設計。假如你聽話馬上開始勤奮地敲代碼,我覺得90%以上該方案都不是什么好方案。can work與work fine之間有著遙遠的距離,改BUG,支持新需求絕對不僅僅是If Else那么簡單。套用Linus大神的話,如果A君或者B君比你更了解你的系統,幫你設計由你實現,那么你就沒有價值,實現的系統一定很爛,不如A君或者B君直接來實現。大神的徒弟不一定就是大神,傳輸大都有損耗。找出所謂需求背后的真正動機,結合當前的系統尋求更好的解決方案。何謂更好,各有各的看法,個人覺得,要保持架構風格的統一,要考慮未來類似需求的普適性,要簡單準確有效。
結語
以上List處于開放狀態,歡迎批評,歡迎加內容。一家之言,還請多包涵。
總結
- 上一篇: Linux 命令平时积累
- 下一篇: 堆栈溢出从入门到提高