標籤:編寫 成員變數 容器 一致性 資訊 path 表格 字元 輸入
1. 應用範圍
本規範應用於採用J2EE規範的項目中,所有項目中的JAVA代碼(含JSP,SERVLET,JAVABEAN,EJB)均應遵守這個規範。同時,也可作為其它項目的參考。
2. 設計類和方法
2.1 建立具有很強內聚力的類
方法的重要性往往比類的重要性更容易理解,方法是指執行一個統一函數的一段代碼。類常被錯誤的視為是一個僅僅用於存放方法的容器。有些開發人員甚至把這種思路作了進一步的發揮,將他們的所有方法放入單個類之中。
之所以不能正確的認識類的功能,原因之一是類的實現實際上並不影響程式的執行。當一個工程被編譯時間,如果所有方法都放在單個類中或者放在幾十個類中,這沒有任何關係。雖然類的數量對代碼的執行並無太大的影響,但是當建立便於調試和維護的代碼時,類的數量有時會帶來很大的影響。
類應該用來將相關的方法組織在一起。
當類包含一組緊密關聯的方法時,該類可以說具有強大的內聚力。當類包含許多互不相關的方法時,該類便具有較弱的內聚力。應該努力建立內聚力比較強的類。
大多數工程都包含許多並不十分適合與其他方法組合在一起的方法。在這種情況下,可以為這些不合群的方法建立一個綜合性收容類。
建立類時,應知道“模組化”這個術語的含義是什麼。類的基本目的是建立相當獨立的程式單元。
2.2 建立鬆散串連和高度專用的方法
1. 使所有方法都執行專門的任務
每個方法都應執行一項特定的任務,它應出色的完成這項任務。應避免建立執行許多不同任務的方法。
建立專用方法有許多好處。首先調試將變得更加容易。
2. 盡量使方法成為自成一體的獨立方法
當一個方法依賴於其他方法的調用時,稱為與其他方法緊密串連的方法。緊密串連的方法會使調試和修改變得比較困難,因為它牽涉到更多的因素。鬆散串連的方法優於緊密串連的方法,但你不可能使每個方法都成為獨立的方法。
若要使方法具備較強的獨立性,方法之一是盡量減少類變數。
建立方法時,設法將每個方法視為一個黑箱,其他常式不應要求瞭解該方法的內部工作情況,該方法也不應要求瞭解它外面的工程情況。這就是為什麼你的方法應依靠參數而不應依靠全域變數的原因。
建立專用方法時,請考慮下列指導原則:
1) 將複雜進程放入專用方法。如果應用程式使用複雜的數學公式,請考慮將每個公式放入它自己的方法中。這樣使用這些公式的其他方法就不包含用於該公式的實際代碼。這樣也可以更容易發現與公式相關的問題。
2) 將資料輸入/輸出(I/O)放入專用方法。
3) 將專用方法中可能要修改的代碼隔離。如果你知道某個進程經常變更,請將這個多變的代碼放入專用方法,以便以後可以更容易的進行修改,並減少無意中給其他進程帶來問題的可能性。
4) 將商務規則封裝在專用方法中。商務規則常屬於要修改的代碼類別,應與應用程式的其餘部分隔開。其他方法不應知道商務規則,只有要調用的方法才使用這些規則。
3. 設計類和方法時,要達到下列目的:
1) 建立更加容易調試和維護的方法
2) 建立具有強大內聚力的類
3) 建立高度專用的方法
4) 建立鬆散串連的方法
5) 盡量使方法具有獨立性
6) 提高方法的扇入性
7) 降低方法的扇出性
2.3 編程原則
1. 為方法和類賦予表義性強的名字
為了使代碼更加容易理解,最容易的方法之一是為你的方法賦予表義性強的名字。函數名DoIt、GetIt的可讀性很難與CalculateSalesTax、 RetrieveUserID相比。
由縮寫方法名組成的代碼很難理解和維護,沒有理由再這樣做了。
給方法正確的命名,可使程式工程的調試和維護工作大大的改觀。請認真對待方法命名的工作,不要為了減少鍵入操作量而降低方法的可理解度。
實際應用舉例:
1) 給方法命名時應大小寫字母混合使用。如果句子全使用大寫字母,那麼閱讀起來就非常困難,而大小寫字母混合使用的句子,閱讀起來就很容易。
2) 定義方法名時不要使用縮寫。如果你認為應用程式中的某些工程應使用縮寫,那麼請將這些情況加上注釋,並確保每個人在所有時間內都使用這些縮寫。決不要在某些方法中對某些單詞進行縮寫,而在別的方法中卻不使用縮寫。
2. 為每個方法賦予單個退出點
3. 建立方法時,始終都應顯式地定義它的範圍。
1) 如果你真的想建立一個公用方法,請向代碼閱讀者說明這一點。
2) 通過為每個方法賦予一個明確定義的範圍,可以減少代碼閱讀者需要投入的工作量。應確保你為方法賦予最有意義的範圍。如果一個方法只被同一類中的另一個方法調用,那麼請將它建立成私人方法。如果該方法是從多個類中的多個方法中調用,請將該說明為公用方法。
4. 用參數在方法之間傳遞資料
應盡量避免使用類變數。一般來說,變數的範圍越小越好。為了減少類變數,方法之一是將資料作為參數在不同方法之間傳遞,而不是讓方法共用類變數。
1) 為每個參數指定資料類型。
2) 始終要對數進行檢驗,決不要假設你得資料沒有問題。程式員常犯的一個錯誤是在編寫方法時假設資料沒有問題。在初始編程階段,當編寫調用方法時,這樣的假設並無大礙。這時你完全能夠知道什麼是參數的許可值,並按要求提供這些值。但如果你不對參數的資料進行檢驗,那麼下列情況就會給你帶來很大麻煩:另外某個人建立了一個調用方法,但此人不知道允許的值;你在晚些時候添加了新的調用方法,並錯誤的傳遞了壞資料。
3. 命名規範
所有變數的定義應該遵循匈牙利命名法,它使用3字元首碼來表示資料類型,3個字元的首碼必須小寫,首碼後面是由表意性強的一個單詞或多個單片語成的名字,而且每個單詞的首寫字母大寫,其它字母小寫,這樣保證了對變數名能夠進行正確的斷句。
這樣,在一個變數名就可以反映出變數類型和變數所儲存的值的意義兩方面內容,這使得代碼語句可讀性強、更加容易理解。
3.1 包、類及方法命名
標示符類型
命名規範
例子
包
l 全部小寫。
l 標識符用點號分隔開來。為了使包的名字更易讀,Sun 公司建議包名中的標識符用點號來分隔。
l Sun 公司的標準 java 分配包用標識符 .java 開頭。
l 全域包的名字用你的機構的 Internet 保留網域名開頭 。
局部包:
interface.screens
全域包:
com.rational.www. interface.screens
類,介面
l 類的名字應該使用名詞。
l 每個單詞第一個字母應該大寫。
l 避免使用單詞的縮寫,除非它的縮寫已經廣為人知,如HTTP。
Class Hello ;
Class HelloWorld ;
Interface Apple ;
方法
l 第一個單詞一般是動詞。
l 第一個字母是小些,但是中間單詞的第一個字母是大寫。
l 如果方法返回一個成員變數的值,方法名一般為get+成員變數名,如若返回的值是bool變數,一般以is作為首碼。
l 如果方法修改一個成員變數的值,方法名一般為:set + 成員變數名。
getName();
setName();
isFirst();
變數
l 第一個字母小寫,中間單詞的第一個字母大寫。
l 不要用_或&作為第一個字母。
l 盡量使用短而且具有意義的單詞。
l 單字元的變數名一般只用於生命期非常短暫的變數。i,j,k,m,n一般用於integers;c,d,e一般用於characters。
l 如果變數是集合,則變數名應用複數。
l 命名組件採用匈牙利命名法,所有首碼均應遵循同一個組件名稱縮寫列表。
String myName;
int[] students;
int i;
int n;
char c;
btNew;
(bt是Button的縮寫)
常量
l 所有常量名均全部大寫,單詞間以‘_’隔開。
int MAX_NUM;
3.2 其它
開發人員如果遇到上述表格中未列舉的類型,請書面通知相關管理員,由管理員集中更新列表內容,不得擅自啟用未經確定的新變數首碼。
4. 使用常量
4.1 使用常量
1. 常數很容易在資料輸入時出錯
常數存在的主要問題之一是你很容易在鍵入數字時出錯,從而顛倒了數位位置。例如,當你鍵入數字10876時,很容易的鍵入10867或18076。與處理變數和保留字的方法不同,編譯器並不在乎顛倒了位置和不正確的數字,有時簡單的錯誤造成的問題不會立即表現出來,而當問題表現出來時,它們會以隨機的計算錯誤的形式出現,這些錯誤很難準確定位。用常量來取代常數時,編譯器將在編譯時間檢查常量的有效性。如果常量不存在,編譯器便將這一情況通知你,並拒絕進行編譯,這可以消除錯誤鍵入的數字帶來的問題,只要常量擁有正確的值,使用該常量的所有代碼也有使用該正確值。
2. 常數很難不斷更新
3. 常量使代碼更容易閱讀
使用常量後,得到的一個額外好處是可使建立的代碼更容易閱讀。常數很不直觀。也許你對常數非常瞭解,但其他人則根本看不明白。通過合理的給常量命名,使用這些常量的代碼就變得比較直觀了,更容易閱讀。
為常量賦予較寬的範圍,這與使用變數時的情況不同。在一個應用程式中你決不應該兩次建立相同的常量。如果你發現自己複製了一個常量,請將原始的常量說明轉至較寬的範圍,直到該常量可供引用它的所有方法為止。
5. 變數
5.1 定義有焦點的變數
用於多個目的的變數稱為無焦點(多焦點)的變數。無焦點變數所代表的意義與程式的執行流程有關,當程式處於不同位置時,它所表示的意義是不固定的,這樣就給程式的可讀性和可維護性帶來了麻煩。
5.2 只對常用變數名和長變數名進行縮寫
如果需要對變數名進行縮寫時,一定要注意整個代碼中縮寫規則的一致性。例如,如果在代碼的某些地區中使用Cnt,而在另一些地區中又使用Count,就會給代碼增加不必要的複雜性。
變數名中盡量不要出現縮寫。
5.3 使用統一的量詞
通過在結尾處放置一個量詞,就可建立更加統一的變數,它們更容易理解,也更容易搜尋。例如,請使用strCustomerFirst和strCustomerLast,而不要使用strFirstCustomer和strLastCustomer。
量詞列表:
量詞尾碼
說明
First
一組變數中的第一個
Last
一組變數中的最後一個
Next
一組變數中的下一個變數
Prev
一組變數中的上一個
Cur
一組變數中的當前變數
5.4 使用肯定形式的布爾變數
給布爾變數命名時,始終都要使用變數的肯定形式,以減少其它開發人員在理解布爾變數所代表的意義時的難度。
5.5 為每個變數選擇最佳的資料類型
這樣即能減少對記憶體的需求量,加快代碼的執行速度,又會降低出錯的可能性。用於變數的資料類型可能會影響該變數進行計算所產生的結果。在這種情況下,編譯器不會產生運行期錯誤,它只是迫使該值符合資料類型的要求。這類問題極難尋找。
5.6 盡量縮小變數的範圍
如果變數的範圍大於它應有的範圍,變數可繼續存在,並且在不再需要該變數後的很長時間內仍然佔用資源。
它們的主要問題是,任何類中的任何方法都能對它們進行修改,並且很難跟蹤究竟是何處進行修改的。
佔用資源是範圍涉及的一個重要問題。對變數來說,盡量縮小範圍將會對應用程式的可靠性產生巨大的影響。
6. 代碼的格式化
6.1 對代碼進行格式化時,要達到的目的
1. 通過代碼分割成功能塊和便於理解的程式碼片段,使代碼更容易閱讀和理解;
2. 使用空行和注釋行,將程式中邏輯上不相關的代碼塊分開。比如:變數聲明部分和代碼語句間的分隔;較長的方法中,完成不同功能的代碼塊間的分隔。要避免出現邏輯上混亂的分隔,如:某一邏輯功能代碼塊中間用空行進行了分隔,但是在相鄰功能代碼塊之間卻沒有分隔,這樣會給程式閱讀者造成錯覺。
3. 減少為理解代碼結構而需要做的工作;
4. 使代碼的閱讀者不必進行假設;
5. 使代碼結構儘可能做到格式清楚明了。
6.2 編程原則
1. 要將多個語句放在同一行上
不論是變數聲明,還是語句都不要在一行上書寫多個。
2. 縮排後續行
當你將變數設定為某個值時,所有後續行的縮排位置應與第一行的變數值相同;
當你調用一個方法時,後續行縮排到第一個參數的開始處;
當你將變數或屬性設定為等於運算式的計算結果時,請從後面分割該語句,以確保該運算式儘可能放在同一行上。
3. 在if語句後縮排;
在else語句後縮排
在switch語句後縮排
在case語句後縮排
在do句後縮排
已經用行接續符分割的語句的各個行要縮排
對從屬於行標註的代碼進行縮排。
4. 在執行統一任務的各個語句組之間插入一個空行。好的代碼應由按邏輯順序排列的進程或相關語句組構成。
7. 代碼的注釋
7.1 使用代碼注釋的目的
1. 文字說明代碼的作用(即為什麼要用編寫該代碼,而不是如何編寫);
2. 確指出該代碼的編寫思路和邏輯方法;
3. 人們注意到代碼中的重要轉折點;
4. 使代碼的閱讀者不必在他們的頭腦中模擬運行代碼的執行方法.
7.2 編程原則
1. 用文字說明代碼的作用:
簡單的重複代碼做寫什麼,這樣的注釋幾乎不能給注釋增加什麼資訊.如果你使用好的命名方法來建立直觀明了的代碼那麼這些類型的注釋絕對增加不了什麼資訊.
2. 如果你想違背好的編程原則,請說明為什麼
有的時候你可能需要違背好的編程原則,或者使用了某些不正規的方法,.遇到這種情況時,請用內部注釋來說明你在做什麼和為什麼要這樣做。
技巧性特別高的程式碼片段,一定要加詳細的注釋,不要讓其他開發人員花很長時間來研究一個高技巧但不易理解的程式段。
3. 用注釋來說明何時可能出錯和為什麼出錯
4. 在編寫代碼前進行注釋
給代碼加註釋的方法之一是在編寫一個方法前首先寫上注釋.如果你願意,可以編寫完整句子的注釋或虛擬碼.一旦你用注釋對代碼進行了概述,就可以在注釋之間編寫代碼.
5. 在要注釋的代碼前書寫注釋
注釋一定出現在要注釋的程式段前,不要在某段程式後書寫對這段程式的注釋,先看到注釋對程式的理解會有一定協助。
如果有可能,請在注釋行與上面代碼間加一空行。
6. 純色字元注釋行只用於主要注釋
注釋中要分隔時,請使用一行空注釋行來完成,不要使用純色字元,以保持版面的整潔、清晰。
7. 避免形成注釋框
用星號圍成的注釋框,右邊的星號看起來很好,但它們給注釋增加了任何資訊嗎?實際上這會給編寫或編輯注釋的人增加許多工作。
8. 增強注釋的可讀性
注釋是供人閱讀的,而不是讓電腦閱讀的。
1) 使用完整的語句。雖然不必將注釋分成段落(最好也不要分成段落),但你應盡量將注釋寫成完整的句子。
2) 避免使用縮寫。縮寫常使注釋更難閱讀,人們常用不同的方法對相同的單詞進行縮寫,這會造成許多混亂,如果必須對詞彙縮寫,必須做到統一。
3) 將整個單詞大寫,以突出它們的重要性。若要使人們注意注釋中的一個或多個單詞,請全部使用大寫字母。
9. 對注釋進行縮排,使之與後隨的語句對齊。
注釋通常位於它們要說明的代碼的前面。為了從視覺上突出注釋與它的代碼之間的關係,請將注釋縮排,使之與代碼處於同一個層次上。
10. 為每個方法賦予一個注釋標題
每個方法都應有一個注釋標題。方法的注釋標題可包含多個文字項,比如輸入參數、傳回值、原始作者、最後編輯該方法的程式員、上次修改日期、著作權資訊。
11. 當行章節附註釋用在上面這種程式碼片段結構中時,它們會使代碼更難閱讀。
使用多個行章節附註釋時(比如用於方法頂部的多個變數說明),應使它們互相對齊。這可使它們稍容易閱讀一些。
12. 何時書寫注釋
1) 請在每個if語句的前面加上注釋。
2) 在每個switch語句的前面加上注釋。與if語句一樣,switch語句用於評估對程式執行產生影響的運算式。
3) 在每個迴圈的前面加上注釋。每個迴圈都有它的作用,許多情況下這個作用不清楚直觀。
7.3 注釋那些部分
項目
注釋哪些部分
實參/
參數
參數類型
參數用來做什麼
任何約束或前提條件
樣本
欄位/
欄位/屬性
欄位描述
注釋所有使用的不變數
樣本
並行事件
可見度決策
類
類的目的
已知的問題
類的開發/維護曆史
注釋出採用的不變數
並行策略
編譯單元
每一個類/類內定義的介面,含簡單的說明
檔案名稱和/或標識資訊
著作權資訊
介面
目的
它應如何被使用以及如何不被使用
局部變數
用處/目的
成員函數注釋
成員函數做什麼以及它為什麼做這個
哪些參數必須傳遞給一個成員函數
成員函數返回什麼
已知的問題
任何由某個成員函數拋出的異常
可見度決策
成員函數是如何改變對象的
包含任何修改代碼的曆史
如何在適當情況下調用成員函數的例子適用的前提條件和後置條件
成員函數內部注釋
控制結構
代碼做了些什麼以及為什麼這樣做
局部變數
難或複雜的代碼
處理順序
7.4 樣本
7.4.1 塊注釋:
主要用來描述檔案,類,方法,演算法等。一般用在文檔和方法的前面,也可以放在文檔的任何地方。以‘/*’開頭,‘*/’結尾。例:
……
/*
* 注釋
*/
……
7.4.2 行注釋:
主要用在方法內部,對代碼,變數,流程等進行說明。與塊注釋格式相似,但是整個注釋佔據一行。例:
……
/* 注釋 */
……
7.4.3 尾隨注釋:
與行注釋功能相似,放在代碼的同行,但是要與代碼之間有足夠的空間,便於分清。例:
int m=4 ; /* 注釋 */
如果一個程式塊內有多個尾隨注釋,每個注釋的縮排應該保持一致。
7.4.4 行章節附註釋:
與行注釋功能相似,放在每行的最後,或者佔據一行。以‘//’開頭。
7.4.5 文檔注釋:
與塊注釋相似,但是可以被javadoc處理,產生HTML檔案。以‘/**’開頭,‘*/’結尾。文檔注釋不能放在方法或程式塊內。例:
/**
注釋
*/
8. 運算式和語句
8.1 每行應該只有一條語句。
8.2 if-else,if-elseif語句,任何情況下,都應該有“{”,“}”,格式如下:
if (condition) {
statements;
} else if (condition) {
statements;
} else{
statements;
}
8.3 for語句格式如下:
for (initialization; condition; update) {
statements;
}
如果語句為空白:
for (initialization; condition; update) ;
8.4 while語句格式如下:
while (condition) {
statements;
}
如果語句為空白:
while (condition);
8.5 do-while語句格式如下:
do {
statements;
} while (condition);
8.6 switch語句,每個switch裡都應包含default子語句,格式如下:
switch (condition) {
case ABC:
statements;
/* falls through */
case DEF:
statements;
break;
case XYZ:
statements;
break;
default:
statements;
break;
}
8.7 try-catch語句格式如下:
try {
statements;
} catch (ExceptionClass e) {
statements;
} finally {
statements;
}
9. 錯誤處理和例外狀況事件
通常的思想是只對錯誤採用異常處理:邏輯和編程錯誤,設定錯誤,被破壞的資料,資源耗盡,等等。
通常的法則是系統在正常狀態下以及無重載和硬體失效狀態下,不應產生任何異常。異常處理時可以採用適當的日誌機制來報告異常,包括異常發生的時刻。不要使用異常實現來控製程序流程結構。
10. 封裝、事務
1. 非商務公用群組件單獨封裝
2. 每一個商務程序單獨封裝
3. 一次方法(組件)的調用應能完成某一項功能或流程,即符合完整性
4. 一次方法(組件)的調用符合ACID事務性
5. 多次方法(組件)的調用應包含在一個事務中
11. 可移植性
1. 盡量不要使用已經被標為不贊成使用的類或方法。
2. 如果需要換行的話,盡量用 println 來代替在字串中使用"\n"。
3. 用separator()方法代替路徑中的”/”或”\” 。
4. 用pathSeptarator()方法代替路徑中的 ” : ” 或 ” ;” 。
java 編程規範