1. 程式人生 > >開發規約-程式設計規範

開發規約-程式設計規範

一、命名規約

1 【強制】程式碼中的命名均不能以下劃線或美元符號開始,也不能以下劃線或美元符號結束。
反例: name / __name / O b j e c t /

n a m e / n a m e Object / name / name
/ Object$

2 【強制】程式碼中的命名嚴禁使用拼音與英文混合的方式,更不允許直接使用中文的方式。
3 【強制】類名使用 UpperCamelCase 風格,必須遵從駝峰形式,但以下情形例外:(領域模型 的相關命名)DO / BO / DTO / VO等。
正例:MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion
反例:macroPolo / UserDo / XMLService / TCPUDPDeal / TAPromotion

4 【強制】方法名、引數名、成員變數、區域性變數都統一使用 lowerCamelCase 風格,必須遵從 駝峰形式。


正例: localValue / getHttpMessage() / inputUserId

5 【強制】常量命名全部大寫,單詞間用下劃線隔開,力求語義表達完整清楚,不要嫌名字長。
6 【強制】POJO 類中布林型別的變數,都不要加 is,否則部分框架解析會引起序列化錯誤。
反例:定義為基本資料型別boolean isSuccess;的屬性,它的方法也是isSuccess(),RPC 框架在反向解析的時候,“以為”對應的屬性名稱是 success,導致屬性獲取不到,進而丟擲異 常。

7 【強制】包名統一使用小寫,點分隔符之間有且僅有一個自然語義的英語單詞。包名統一使用 單數形式,但是類名如果有複數含義,類名可以使用複數形式。
正例: 應用工具類包名為com.alibaba.open.util、類名為MessageUtils(此規則參考 spring 的框架結構)

8 【強制】杜絕完全不規範的縮寫,避免望文不知義。
反例: AbstractClass“縮寫”命名成 AbsClass;condition“縮寫”命名成 condi,此類 隨意縮寫嚴重降低了程式碼的可閱讀性。

9 【強制】對於 Service 和 DAO 類,基於 SOA 的理念,暴露出來的服務一定是介面,內部的實現類用 Impl 的字尾與介面區別。
正例:CacheServiceImpl 實現 CacheService 介面。

10 【強制】各層命名規約:
A) Service/DAO層方法命名規約

  1. 獲取單個物件的方法用selectOne/get做字首。
  2. 獲取多個物件的方法用select/list做字首。
  3. 獲取統計值的方法用count/selectCount做字首。
  4. 插入的方法用insert/save做字首。
  5. 刪除的方法用delete/remove做字首。
  6. 修改的方法用update做字首。

B) 領域模型命名規約

  1. 資料物件:xxxDO,xxx即為資料表名。
  2. 資料傳輸物件:xxxDTO,xxx為業務領域相關的名稱。
  3. 展示物件:xxxVO,xxx一般為網頁名稱。
  4. POJO是DO/DTO/BO/VO的統稱,禁止命名成xxxPOJO。

二、常量定義

11【強制】不允許出現任何魔法值(即未經定義的常量)直接出現在程式碼中。
反例: String key=“Id#taobao_”+tradeId;
cache.put(key, value);

12 不要使用一個常量類維護所有常量,應該按常量功能進行歸類,分開維護。如:快取 相關的常量放在類:CacheConsts 下;系統配置相關的常量放在類:ConfigConsts 下。

三、格式規約

public static void main(String args[]) {
		// 縮排 4 個空格
		String say = "hello";
		// 運算子的左右必須有一個空格
		int flag = 0;
		// 關鍵詞 if 與括號之間必須有一個空格,括號內的 f 與左括號,0 與右括號不需要空格
		if (flag == 0) {
				System.out.println(say);
		}
		// 左大括號前加空格且不換行;左大括號後換行
		if (flag == 1) {
				System.out.println("world");
				// 右大括號前換行,右大括號後有 else,不用換行 ——禁止用於商業用途,違者必究——
		} else {
				System.out.println("ok");
				// 在右大括號後直接結束,則必須換行
		}
}

14 【強制】單行字元數限制不超過 120 個,超出需要換行,換行時遵循如下原則:

  1. 第二行相對第一行縮排 4 個空格,從第三行開始,不再繼續縮排,參考示例。
  2. 運算子與下文一起換行。
  3. 方法呼叫的點符號與下文一起換行。
  4. 在多個引數超長,逗號後進行換行。
  5. 在括號前不要換行,見反例。
正例
 
StringBuffer sb = new StringBuffer();
//超過 120 個字元的情況下,換行縮排 4 個空格,並且方法前的點符號一起換行
sb.append("zi").append("xin")...
.append("huang")...
.append("huang")...
.append("huang");
 
反例
 
StringBuffer sb = new StringBuffer();
//超過 120 個字元的情況下,不要在括號前換行
sb.append("zi").append("xin")...append
("huang");
//引數很多的方法呼叫可能超過 120 個字元,不要在逗號前換行
method(args1, args2, args3, ...
, argsX);

四、控制語句

// 反例
if (condition) statements;
// 正例
if (condition) {}
if (condition) {
...
}

五、註釋規約

16 【強制】所有的類都必須新增建立者資訊。
*17【強制】類、類屬性、類方法的註釋必須使用 Javadoc 規範,使用/內容/格式,不得使用 //xxx 方式。
說明:在 IDE 編輯視窗中,Javadoc 方式會提示相關注釋,生成 Javadoc 可以正確輸出相應注 釋;在 IDE 中,工程呼叫方法時,不進入方法即可懸浮提示方法、引數、返回值的意義,提高 閱讀效率。

18 【強制】不要捕獲 Java 類庫中定義的繼承自 RuntimeException 的執行時異常類,如: IndexOutOfBoundsException / NullPointerException,這類異常由程式設計師預檢查 來規避,保證程式健壯性。

//正例:
if(obj != null) {...}
 
//反例:
try { obj.method() } catch(NullPointerException e){...}

19【強制】捕獲異常是為了處理它,不要捕獲了卻什麼都不處理而拋棄之,如果不想處理它,請 將該異常拋給它的呼叫者。最外層的業務使用者,必須處理異常,將其轉化為使用者可以理解的 內容。

20【強制】finally 塊必須對資源物件、流物件進行關閉,有異常也要做 try-catch。 說明:如果 JDK7,可以使用 try-with-resources 方式。

21【強制】捕獲異常與拋異常,必須是完全匹配,或者捕獲異常是拋異常的父類。 說明:如果預期對方拋的是繡球,實際接到的是鉛球,就會產生意外情況。

六、日誌規約

22【強制】應用中不可直接使用日誌系統(Log4j、Logback)中的 API,而應依賴使用日誌框架
SLF4J 中的 API,使用門面模式的日誌框架,有利於維護和各個類的日誌處理方式統一。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(Abc.class);

23【強制】對 trace/debug/info 級別的日誌輸出,必須使用條件輸出形式或者使用佔位符的方式。

說明:logger.debug("Processing trade with id: " + id + " symbol: " + symbol); 如果日誌級別是 warn,上述日誌不會列印,但是會執行字串拼接操作,如果 symbol 是物件, 會執行 toString()方法,浪費了系統資源,執行了上述操作,最終日誌卻沒有列印。
 
正例:(條件)
if (logger.isDebugEnabled()) {
logger.debug("Processing trade with id: " + id + " symbol: " + symbol);
}
//正例:(佔位符)
logger.debug("Processing trade with id: {} symbol : {} ", id, symbol);

七、其他

24【強制】獲取當前毫秒數 System.currentTimeMillis(); 而不是 new Date().getTime();
說明:如果想獲取更加精確的納秒級時間值,用 System.nanoTime()。在 JDK8 中,針對統計 時間等場景,推薦使用 Instant 類。