編寫代碼的規範

1、儘可能使用接口,而後使用類實現接口,以提升程序的靈活性。 
2、一行不要超過80個字符 
3、儘可能不要手工更改計算機生成的代碼,若必須修改,必定要改爲和計算機生成的代碼風格同樣。 
4、關鍵的語句(包括聲明關鍵的變量)必需要寫註釋。 
5、建議局部變量在最接近使用它的地方聲明。 
6、不要使用goto系列語句,除非是用在跳出深層循環時。 
7、避免寫超過5個參數的方法。若是要傳遞多個參數,則使用結構。 
8、避免書寫代碼量過大的try…catch模塊。 
9、避免在同一個文件中放置多個類。 
10、生成和構建一個長的字符串時,必定要使用StringBuilder類型,而不是string類型。 
11、switch語句必定要有default語句來處理意外狀況。 
12、對於if語句,應該使用一對「{}」把語句塊包含起來。 
1三、儘可能不使用this關鍵字引用。

第一命名:java

  類名的話,使用大駝峯,方法名和變量名採用小駝峯的樣式. 最好可以見名知意      例如程序員

public class Demo
{
    public void demoBind()
    {

    }
}
string strUserName;

Java代碼規範

 

本Java代碼規範以SUN的標準Java代碼規範爲基礎,爲適應咱們公司的實際須要,可能會作一些修改。本文檔中沒有說明的地方,請參看SUN Java標準代碼規範。若是兩邊有衝突,以本文檔爲準。sql

1. 標識符命名規範

1.1 概述

標識符的命名力求作到統1、達意和簡潔。安全

1.1.1 統一

統一是指,對於同一個概念,在程序中用同一種表示方法,好比對於供應商,既能夠用supplier,也能夠用provider,可是咱們只能選定一個使用,至少在一個Java項目中保持統一。統一是做爲重要的,若是對同一律念有不一樣的表示方法,會使代碼混亂難以理解。即便不能取得好的名稱,可是隻要統一,閱讀起來也不會太困難,由於閱讀者只要理解一次。session

1.1.2 達意

達意是指,標識符能準確的表達出它所表明的意義,好比: newSupplier, OrderPaymentGatewayService等;而 supplier1, service2,idtts等則不是好的命名方式。準確有兩成含義,一是正確,而是豐富。若是給一個表明供應商的變量起名是 order,顯然沒有正確表達。一樣的,supplier1, 遠沒有targetSupplier意義豐富。app

1.1.3 簡潔

簡潔是指,在統一和達意的前提下,用盡可能少的標識符。若是不能達意,寧願不要簡潔。好比:theOrderNameOfTheTargetSupplierWhichIsTransfered 太長, transferedTargetSupplierOrderName則較好,可是transTgtSplOrdNm就很差了。省略元音的縮寫方式不要使用,咱們的英語每每尚未好到看得懂奇怪的縮寫。eclipse

1.1.4 駱駝法則

Java中,除了包名,靜態常量等特殊狀況,大部分狀況下標識符使用駱駝法則,即單詞之間不使用特殊符號分割,而是經過首字母大寫來分割。好比: SupplierName, addNewContract,而不是 supplier_name, add_new_contract。ide

1.1.5 英文 vs 拼音

儘可能使用通俗易懂的英文單詞,若是不會能夠向隊友求助,實在不行則使用漢語拼音,避免拼音與英文混用。好比表示歸檔,用archive比較好, 用pigeonhole則很差,用guiDang尚可接受。svn

1.2 包名

使用小寫字母如 com.xxx.settlment,不要 com.xxx.Settlement
單詞間不要用字符隔開,好比 com.xxx.settlment.jsfutil,而不要com.xxx.settlement.jsf_util優化

1.3 類名

1.3.1 首字母大寫

類名要首字母大寫,好比 SupplierService, PaymentOrderAction;不要 supplierService, paymentOrderAction.

1.3.2 後綴

類名每每用不一樣的後綴表達額外的意思,以下表:

後綴名 意義 舉例
Service 代表這個類是個服務類,裏面包含了給其餘類提同業務服務的方法 PaymentOrderService
Impl 這個類是一個實現類,而不是接口 PaymentOrderServiceImpl
Inter 這個類是一個接口 LifeCycleInter
Dao 這個類封裝了數據訪問方法 PaymentOrderDao
Action 直接處理頁面請求,管理頁面邏輯了類 UpdateOrderListAction
Listener 響應某種事件的類 PaymentSuccessListener
Event 這個類表明了某種事件 PaymentSuccessEvent
Servlet 一個Servlet PaymentCallbackServlet
Factory 生成某種對象工廠的類 PaymentOrderFactory
Adapter 用來鏈接某種之前不被支持的對象的類 DatabaseLogAdapter
Job 某種按時間運行的任務 PaymentOrderCancelJob
Wrapper 這是一個包裝類,爲了給某個類提供沒有的能力 SelectableOrderListWrapper
Bean 這是一個POJO MenuStateBean

1.4 方法名

首字母小寫,如 addOrder() 不要 AddOrder()
動詞在前,如 addOrder(),不要orderAdd()
動詞前綴每每表達特定的含義,以下表:

前綴名 意義 舉例
create 建立 createOrder()
delete 刪除 deleteOrder()
add 建立,暗示新建立的對象屬於某個集合 addPaidOrder()
remove 刪除 removeOrder()
init或則initialize 初始化,暗示會作些諸如獲取資源等特殊動做 initializeObjectPool
destroy 銷燬,暗示會作些諸如釋放資源的特殊動做 destroyObjectPool
open 打開 openConnection()
close 關閉 closeConnection()<
read 讀取 readUserName()
write 寫入 writeUserName()
get 得到 getName()
set 設置 setName()
prepare 準備 prepareOrderList()
copy 複製 copyCustomerList()
modity 修改 modifyActualTotalAmount()
calculate 數值計算 calculateCommission()
do 執行某個過程或流程 doOrderCancelJob()
dispatch 判斷程序流程轉向 dispatchUserRequest()
start 開始 startOrderProcessing()
stop 結束 stopOrderProcessing()
send 發送某個消息或事件 sendOrderPaidMessage()
receive 接受消息或時間 receiveOrderPaidMessgae()
respond 響應用戶動做 responseOrderListItemClicked()
find 查找對象 findNewSupplier()
update 更新對象 updateCommission()

find方法在業務層儘可能表達業務含義,好比 findUnsettledOrders(),查詢未結算訂單,而不要findOrdersByStatus()。 數據訪問層,find,update等方法能夠表達要執行的sql,好比findByStatusAndSupplierIdOrderByName(Status.PAID, 345)

1.5 域(field)名

1.5.1 靜態常量

全大寫用下劃線分割,如


public static find String ORDER_PAID_EVENT = "ORDER_PAID_EVENT";

1.5.2 枚舉

全大寫,用下劃線分割,如

public enum Events {
ORDER_PAID,
ORDER_CREATED
}

1.5.3 其餘

首字母小寫,駱駝法則,如:

public String orderName;

1.6 局部變量名

參數和局部變量名首字母小寫,駱駝法則。儘可能不要和域衝突,儘可能表達這個變量在方法中的意義。

2. 代碼格式

用空格字符縮進源代碼,不要用tab,每一個縮進4個空格。

2.1 源文件編碼

源文件使用utf-8編碼,結尾用unix n 分格。

2.2 行寬

行寬度不要超過130。

2.3 包的導入

刪除不用的導入,儘可能不要使用整個包的導入。在eclipse下常用快捷鍵 ctrl+shift+o 修正導入。

2.4 類格式

2.5 域格式

每行只能聲明一個域。
域的聲明用空行隔開。

2.5 方法格式

2.6 代碼塊格式

2.6.1 縮進風格

大括號的開始在代碼塊開始的行尾,閉合在和代碼塊同一縮進的行首,例如:

package com.test;

public class TestStyle extends SomeClass implements AppleInter, BananaInter {
public static final String THIS_IS_CONST = "CONST VALUE";

private static void main(String[] args) {
int localVariable = 0;
}

public void compute(String arg) {
if (arg.length() > 0) {
System.out.println(arg);
}

for (int i = 0; i < 10; i++) {
System.out.println(arg);
}

while (condition) {

}

do {
otherMethod();
} while (condition);

switch (i) {
case 0:
callFunction();
break;
case 1:
callFunctionb();
break;
default:
break;
}
}
}

2.6.2 空格的使用

2.6.2.1 表示分割時用一個空格

不能這樣:

if ( a > b ) {
//do something here
};

2.6.2.2 二元三元運算符兩邊用一個空格隔開

以下:

a + b = c;
b - d = e;
return a == b ? 1 : 0;

不能以下:


a+b=c;
b-d=e;
return a==b?1:0;

2.6.2.3 逗號語句後如不還行,緊跟一個空格

以下:

call(a, b, c);

不能以下:

call(a,b,c);

2.6.3 空行的使用

空行能夠表達代碼在語義上的分割,註釋的做用範圍,等等。將相似操做,或一組操做放在一塊兒不用空行隔開,而用空行隔開不一樣組的代碼, 如圖:

order = orderDao.findOrderById(id);

//update properties
order.setUserName(userName);
order.setPrice(456);
order.setStatus(PAID);

orderService.updateTotalAmount(order);

session.saveOrUpdate(order);

上例中的空行,使註釋的做用域很明顯.

  • 連續兩行的空行表明更大的語義分割。
  • 方法之間用空行分割
  • 域之間用空行分割
  • 超過十行的代碼若是還不用空行分割,就會增長閱讀困難

3. 註釋規範

3.1 註釋 vs 代碼

  • 註釋宜少二精,不宜多而濫,更不能誤導
  • 命名達意,結構清晰, 類和方法等責任明確,每每不須要,或者只須要不多註釋,就可讓人讀懂;相反,代碼混亂,再多的註釋都不能彌補。因此,應當先在代碼自己下功夫。
  • 不能正確表達代碼意義的註釋,只會損害代碼的可讀性。
  • 過於詳細的註釋,對顯而易見的代碼添加的註釋,羅嗦的註釋,還不如不寫

  • 註釋要和代碼同步,過多的註釋會成爲開發的負擔
  • 註釋不是用來管理代碼版本的,若是有代碼不要了,直接刪除,svn會有記錄的,不要註釋掉,不然之後沒人知道那段註釋掉的代碼該不應刪除。

3.2 Java Doc

代表類、域和方法等的意義和用法等的註釋,要以javadoc的方式來寫。Java Doc是個類的使用者來看的,主要介紹 是什麼,怎麼用等信息。凡是類的使用者須要知道,都要用Java Doc 來寫。非Java Doc的註釋,每每是個代碼的維護者看的,着重告述讀者爲何這樣寫,如何修改,注意什麼問題等。 以下:

/**
* This is a class comment
*/
public class TestClass {
/**
* This is a field comment
*/
public String name;

/**
* This is a method comment
*/
public void call() {

}
}

3.3 塊級別註釋

3.3.1 塊級別註釋,單行時用 //, 多行時用 /* .. */。

3.3.2 較短的代碼塊用空行表示註釋做用域

3.3.3 較長的代碼塊要用


/*------ start: ------*/

/*-------- end: -------*/

包圍
如:

/*----------start: 訂單處理 ------- */
//取得dao
OrderDao dao = Factory.getDao("OrderDao");

/* 查詢訂單 */
Order order = dao.findById(456);

//更新訂單
order.setUserName("uu");
order.setPassword("pass");
order.setPrice("ddd");

orderDao.save(order);
/*----------end: 訂單處理 ------- */

3.3.4 能夠考慮使用大括號來表示註釋範圍

使用大括號表示註釋做用範圍的例子:

/*----------訂單處理 ------- */
{
//取得dao
OrderDao dao = Factory.getDao("OrderDao");

/* 查詢訂單 */
Order order = dao.findById(456);

//更新訂單
order.setUserName("uu");
order.setPassword("pass");
order.setPrice("ddd");

orderDao.save(order);
}

3.4 行內註釋

行內註釋用 // 寫在行尾

4 最佳實踐和禁忌

4.1 每次保存的時候,都讓你的代碼是最美的

程序員都是懶惰的,不要想着等我完成了功能,再來優化代碼的格式和結構,等真的把功能完成,不多有人會再願意回頭調整代碼。

4.2 使用log而不是System.out.println()

log能夠設定級別,能夠控制輸出到哪裏,容易區分是在代碼的什麼地方打印的,而System.out.print則不行。並且,System.out.print的速度很慢。因此,除非是有意的,不然,都要用log。至少在提交到svn以前把System.out.print換成log。

4.3 每一個if while for等語句,都不要省略大括號{}

看下面的代碼:

if (a > b)
a++;

若是在之後維護的時候,須要在a > b 時,把b++,一步當心就會寫成:

if (a > b)
a++;
b++;

這樣就錯了,由於不管a和b是什麼關係,b++都會執行。 若是一開始就這樣寫:

if (a > b) {
a++;
}

相信沒有哪一個笨蛋會把b++添加錯的。並且,這個大括號使做用範圍更明顯,尤爲是後面那行很長要折行時。

4.4 善用TODO:

在代碼中加入 //TODO: ,大部分的ide都會幫你提示,讓你知道你還有什麼事沒有作。好比:

if (order.isPaid()) {
//TODO: 更新訂單
}

4.5 在須要留空的地方放一個空語句或註釋,告述讀者,你是故意的

好比:

if (!exists(order)) {
;
}

或:


if (!exists(order)) {
//nothing to do
}

4.6 不要再對boolean值作true false判斷

好比:

if (order.isPaid() == true) {
// Do something here
}

不如寫成:

if (order.isPaid()) {
//Do something here
}

後者讀起來就非常 if order is paid, .... 要比 if order's isPaid method returns true, … 更容易理解

4.7 減小代碼嵌套層次

代碼嵌套層次達3層以上時,通常人理解起來都會困難。下面的代碼是一個簡單的例子:

public void demo(int a, int b, int c) {
if (a > b) {
if (b > c) {
doJobA();
} else if (b < c) {
doJobB()
}
} else {
if (b > c) {
if (a < c) {
doJobC();
}
}
}
}

減小嵌套的方法有不少:

  • 合併條件
  • 利用 return 以省略後面的else
  • 利用子方法

好比上例,合併條件後成爲:

public void demo(int a, int b, int c) {
if (a > b && b > c) {
doJobA();
}
if (a > b && c > b) {
doJobB();
}
if (a <= b && c < b && a < c) {
doJobC();
}
}

若是利用return 則成爲:

public void demo(int a, int b, int c) {
if (a > b) {
if (b > c) {
doJobA();
return;
}
doJobB()
return;
}

if (b > c) {
if (a < c) {
doJobC();
}
}
}

利用子方法,就是將嵌套的程序提取出來放到另外的方法裏。

4.8 程序職責單一

關注點分離是軟件開發的真理。人類自因此可以完成複雜的工做,就是由於人類可以將工做分解到較小級別的任務上,在作每一個任務時關注更少的東西。讓程序單元的職責單一,可使你在編寫這段程序時關注更少的東西,從而下降難度,減小出錯。

4.9 變量的聲明,初始化和被使用盡可能放到一塊兒

比方說以下代碼:

int orderNum= getOrderNum();

//do something withou orderNum here

call(orderNum);

上例中的註釋處表明了一段和orderNum不相關的代碼。orderNum的聲明和初始化離被使用的地方相隔了不少行的代碼,這樣作很差,不如這樣:

//do something withou orderNum here

int orderNum= getOrderNum();
call(orderNum);

4.10 縮小變量的做用域

能用局部變量的,不要使用實例變量,能用實例變量的,不要使用類變量。變量的生存期越短,覺得着它被誤用的機會越小,同一時刻程序員要關注的變量的狀態越少。實例變量和類變量默認都不是線程安全的,局部變量是線程安全的。好比以下代碼:

public class OrderPayAction{
private Order order;

public void doAction() {
order = orderDao.findOrder();
doJob1();
doJob2();
}

private void doJob1() {
doSomething(order);
}

private void doJob2() {
doOtherThing(order);
}
}

上例中order只不過擔當了在方法間傳遞參數之用,用下面的方法更好:

public class OrderPayAction{

public void doAction() {
order = orderDao.findOrder();
doJob1(order);
doJob2(order);
}

private void doJob1(Order order) {
doSomething(order);
}

private void doJob2(Order order) {
doOtherThing(order);
}
}

4.11 儘可能不要用參數來帶回方法運算結果

好比:

public void calculate(Order order) {
int result = 0;
//do lots of computing and store it in the result

order.setResult(result);
}

public void action() {
order = orderDao.findOrder();
calculate(order);

// do lots of things about order
}

例子中calculate方法經過傳入的order對象來存儲結果, 不如以下寫:

public int calculate(Order order) {
int result = 0;
//do lots of computing and store it in the result

return result;
}

public void action() {
order = orderDao.findOrder();
order.setResult(calculate(order));

// do lots of things about order}

相關文章
相關標籤/搜索