編寫代碼的規范


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

第一命名:

  類名的話,使用大駝峰,方法名和變量名采用小駝峰的樣式. 最好能夠見名知意      例如

public class Demo
{
    public void demoBind()
    {

    }
}
string strUserName;

Java代碼規范

 

本Java代碼規范以SUN的標准Java代碼規范為基礎,為適應我們公司的實際需要,可能會做一些修改。本文檔中沒有說明的地方,請參看SUN Java標准代碼規范。如果兩邊有沖突,以本文檔為准。

1. 標識符命名規范

1.1 概述

標識符的命名力求做到統一、達意和簡潔。

1.1.1 統一

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

1.1.2 達意

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

1.1.3 簡潔

簡潔是指,在統一和達意的前提下,用盡量少的標識符。如果不能達意,寧願不要簡潔。比如:theOrderNameOfTheTargetSupplierWhichIsTransfered 太長, transferedTargetSupplierOrderName則較好,但是transTgtSplOrdNm就不好了。省略元音的縮寫方式不要使用,我們的英語往往還沒有好到看得懂奇怪的縮寫。

1.1.4 駱駝法則

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

1.1.5 英文 vs 拼音

盡量使用通俗易懂的英文單詞,如果不會可以向隊友求助,實在不行則使用漢語拼音,避免拼音與英文混用。比如表示歸檔,用archive比較好, 用pigeonhole則不好,用guiDang尚可接受。

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
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM