一、目的   


  對于程式碼,首要要求是它必須正確,能夠按照程式員的真實思想去運作;第二個的要求是程式碼必須清晰易懂,使別的程式員能夠容易理解程式碼所進行的實際工作。
    在軟體工程領域,源程式的風格統一標誌著可維護性、可讀性,是軟體項目的一個重要組成部分。而目前還沒有成文的編碼風格文檔,以致于很多時候,程式員沒有一個
    共同的標準可以遵守,編碼風格各異,程式可維護性差、可讀性也很差。透過建立程式碼編寫規範,形成開發小組編碼約定,提升程式的可靠性、可讀性、可修改性、可
    維護性、可繼承性和一致性,可以保證程式程式碼的質量,繼承軟體開發成果,充分利用資源,使開發人員之間的工作成果可以共享。


    本文在參考業界已有的編碼風格的基礎上,描述了一個基于 JBuilder 的項目風格,力求一種統一的編程風格,並從整體編碼風格、程式碼文件風格、函式編寫風格、變數
    風格、註釋風格等幾個方面進行闡述。(這些規範並不是一定要絕對遵守,但是一定要讓程式有良好的可讀性)



二、整體編碼風格


1、縮格


    縮格建議以4個空格為單位。建議在 Tools/Editor Options 中設置 Editor 頁面的Block ident為4,Tab Size 為8。預處理語句、全域數據、標題、附加說明、函式說明、
    標號等均頂格書寫。語句塊的"{"、"}"配對對齊,並與其前一行對齊,語句塊類的語句縮格建議每個"{"、"}"單獨佔一行,便于匹對。JBuilder 中的默認模式是開始的"{"
    不是單獨一行,建議更改成上述格式(在 Project/Default Project Properties 中設置 Code Style 中選擇 Braces 為 Next line)。


2、空格


    原則上變數、類、常量數據和函式在其類型,修飾名稱之間適當空格並據情況對齊。關鍵字原則上空一格,如︰if ( ... ) 等。
    運算符的空格規定如下︰"::"、"->"、"["、"]"、"++"、"--"、"~"、"!"、"+"、"-"(指正負號)、" "(引用)等幾個運算符兩邊不加空格
    (其中單目運算符系指與操作數相連的一邊),其它運算符(包括大多數二目運算符和三目運算符"?:"兩邊均加一空格,在作函式定義時還可據情況多空或不空格來對齊,
    但在函式實現時可以不用。","運算符只在其后空一格,需對齊時也可不空或多空格。不論是否有括號,對語句行后加的註釋應用適當空格與語句隔開並儘可能對齊。
    個人認為此項可以依照個人習慣決定遵循與否。


3、對齊


    原則上關係密切的行應對齊,對齊包括類型、修飾、名稱、參數等各部分對齊。另每一行的長度不應超過螢幕太多,必要時適當換行,換行時儘可能在","處或運算符處,
    換行后最好以運算符打頭,並且以下各行均以該語句首行縮格,但該語句仍以首行的縮格為準,即如其下一行為“{”應與首行對齊。


    變數定義最好透過添加空格形成對齊,同一類型的變數最好放在一起。如下例所示︰
int        Value;
int        Result;
int        Length;
Object     currentEntry;


 個人認為此項可以依照個人習慣決定遵循與否。


4、空行


 不得存在無規則的空行,比如說連續十個空行。
 程式文件架構各部分之間空兩行,若不必要也可只空一行,各函式實現之間一般空兩行,由於每個函式還要有函式說明註釋,故通常只需空一行或不空,
 但對于沒有函式說明的情況至少應再空一行。對自己寫的函式,建議也加上“//------”做分隔。
 函式內部數據與程式碼之間應空至少一行,程式碼中適當處應以空行空開,建議在程式碼中出現變數聲明時,在其前空一行。
 類中四個“p”之間至少空一行,在其中的數據與函式之間也應空行。


5、註釋


 註釋是軟體可讀性的具體體現。程式註釋量一般占程式編碼量的20%,軟體工程要求不少于20%。
 程式註釋不能用抽象的語言,類似于"處理"、"循環"這樣的計算機抽象語言,要精確表達出程式的處理說明。
 例如︰"計算淨需求"、"計算第一道工序的加工工時"等。避免每行程式都使用註釋,可以在一段程式的前面加一段註釋,具有明確的處理邏輯。


 註釋必不可少,但也不應過多,不要被動的為寫註釋而寫註釋。以下是四種必要的註釋︰
 
A. 標題、附加說明。


B. 函式、類等的說明。
   對幾乎每個函式都應有適當的說明,通常加在函式實現之前,在沒有函式實現部分的情況下則加在函式原型前,其內容主要是函式的功能、目的、算法等說明,
   參數說明、返回值說明等,必要時還要有一些如特別的軟硬體要求等說明。公用函式、公用類的聲明必須由註解說明其使用方法和設計思路,當然選擇恰當的命
   名格式能夠幫助你把事情解釋得更清楚。


C. 在程式碼不明晰或不可移植處必須有一定的說明。


D. 及少量的其它註釋,如自定義變數的註釋、程式碼書寫時間等。


  註釋有塊註釋和行註釋兩種,分別是指︰"/**/"和"//"建議對A用塊註釋,D用行註釋,B、C則視情況而定,但應統一,至少在一個單元中B類註釋形式應統一。
  具體對不同文件、架構的註釋會在后面詳細說明。


6、程式碼長度


 對于每一個函式建議儘可能控制其程式碼長度為53行左右,超過53行的程式碼要重新考慮將其拆分為兩個或兩個以上的函式。
 函式拆分規則應該一不破壞原有算法為基礎,同時拆分出來的部分應該是可以重複利用的。
 對于在多個模塊或者窗體中都要用到的重複性程式碼,完全可以將起獨立成為一個具備公用性質的函式,放置於一個公用模塊中。


7、頁寬


 頁寬應該設置為80字符。
 源程式碼一般不會超過這個寬度, 並導致無法完整顯示, 但這一設置也可以靈活調整. 在任何情況下, 超長的語句應該在一個逗號或者一個操作符后折行.
 一條語句折行后, 應該比原來的語句再縮格2個字符.


8、行數


 一般的集成編程環境下,每屏大概只能顯示不超過50行的程式,所以這個函式大概要5-6屏顯示,在某些環境下要8屏左右才能顯示完。
 這樣一來,無論是讀程式還是修改程式,都會有困難。因此建議把完成比較獨立功能的程式塊抽出,單獨成為一個函式。把完成相同或相近功能的程式塊抽出,
 獨立為一個子函式。可以發現,越是上層的函式越簡單,就是調用幾個子函式,越是底層的函式完成的越是具體的工作。這是好程式的一個標誌。這樣,我們就
 可以在較上層函式裡容易控制整個程式的邏輯,而在底層的函式裡專注于某方面的功能的實現了。



三、程式碼文件風格


所有的 Java(*.java) 文件都必須遵守如下的樣式規則︰


. 文件生成


對于規範的 JAVA 派生類,盡量用 JBuilder 的 Object Gallery 工具來生成文件格式,避免用手工製作的頭文件/實現文件。
 
. package/import


package 行要在 import 行之前,import 中標準的包名要在本地的包名之前,而且按照字母順序排列。如果 import 行中包含了同一個包中的不同子目錄,
則應該用 * 來處理。


package hotlava.net.stats;


import java.io.*;
import java.util.Observable;
import hotlava.util.Application; 
 
這裡 java.io.* 使用來代替InputStream and OutputStream 的。


. 文件頭部註釋


文件頭部註釋主要是表明該文件的一些訊息,是程式的總體說明,可以增強程式的可讀性和可維護性。
文件頭部註釋一般位于 package/imports 語句之后,Class 描述之前。要求至少寫出文件名、創建者、創建時間和內容描述。JBuilder 的 Object Gallery
工具生成的程式碼中會在類、工程文件中等自動添加註釋,我們也要添加一些註釋,其格式應該盡量約束如下︰


/**
 * Title:           確定滑鼠位置類
 * Description:     確定滑鼠當前在哪個作業欄位中並返回作業號
 * @Copyright:      Copyright (c) 2002
 * @Company:        HIT
 * @author:         rivershan
 * @version:        1.0
 * @time:           2002.10.30
 */
 
. Class


接下來的是類的註釋,一般是用來解釋類的。


/**
 * A class representing a set of packet and byte counters
 * It is observable to allow it to be watched, but only
 * reports changes when the current set is complete
 */
 
接下來是類定義,包含了在不同的行的 extends 和 implements


public class CounterSet
  extends Observable
  implements Cloneable


.Class Fields


接下來是類的成員變數︰


/**
 * Packet counters
 */
 
protected int[] packets;
 
public 的成員變數必須生成文檔(JavaDoc)。proceted、private和 package 定義的成員變數如果名字含義明確的話,可以沒有註釋。


. 存取方法
 
接下來是類變數的存取的方法。它只是簡單的用來將類的變數賦值獲取值的話,可以簡單的寫在一行上。(個人認為盡量分行寫)


/**
 * Get the counters
 * @return an array containing the statistical data.  This array has been
 * freshly allocated and can be modified by the caller.
 */
 
public int[] getPackets()
{
  return copyArray(packets, offset);
}


public int[] getBytes()
{
 return copyArray(bytes, offset);
}


public int[] getPackets()
{
 return packets;
}


public void setPackets(int[] packets)
{
 this.packets = packets;
}
 
其它的方法不要寫在一行上


. 構造函式


接下來是構造函式,它應該用遞增的模式寫(比如︰參數多的寫在后面)。


訪問類型("public","private" 等.)和任何"static","final"或"synchronized"應該在一行中,並且方法和參數另寫一行,這樣可以使方法和參數更易讀。


public
CounterSet(int size)
{
   this.size = size;
}


. 克隆方法
 
如果這個類是可以被克隆的,那么下一步就是 clone 方法︰


public
Object clone()
{
 try
   {
     CounterSet obj = (CounterSet)super.clone();
     obj.packets = (int[])packets.clone();
     obj.size = size;
     return obj;
   } 
   catch(CloneNotSupportedException e)
   {
    throw new InternalError("Unexpected CloneNotSUpportedException: "
          + e.getMessage());
   }
}


. 類方法


下面開始寫類的方法︰


/**
 * Set the packet counters
 * (such as when restoring from a database)
 */
protected final
void setArray(int[] r1, int[] r2, int[] r3, int[] r4)
  throws IllegalArgumentException
{
 //
   // Ensure the arrays are of equal size
   //
   if (r1.length != r2.length || r1.length != r3.length || r1.length != r4.length)
  throw new IllegalArgumentException("Arrays must be of the same size");
   System.arraycopy(r1, 0, r3, 0, r1.length);
   System.arraycopy(r2, 0, r4, 0, r1.length);
}


. toString 方法


無論如何,每一個類都應該定義 toString 方法︰


public
String toString()
{
 String retval = "CounterSet: ";
    for (int i = 0; i < data.length(); i++)
    {
       retval += data.bytes.toString();
       retval += data.packets.toString();
    }
    return retval;
}


. main 方法


如果main(String[]) 方法已經定義了, 那么它應該寫在類的底部.



四、函式編寫風格


. 函式的命名


通常,函式的命名也是以能表達函式的動作意義為原則的,一般是由動詞打頭,然後跟上表示動作對象的名詞,各單詞的首字母應該大寫。
另外,還有一些函式命名的通用規則。如取數,則用Get打頭,然後跟上要取的對象的名字;設置數,則用Set打頭,然後跟上要設的對象的名字;
而對象中為了附應消息進行動作的函式,可以命名為On打頭,然後是相應的消息的名稱;進行主動動作的函式,可以命名為Do打頭,然後是相應的動作名稱。
類似的規則還有很多,需要程式員多讀優秀的程式,逐漸累積經驗,才能作出好的函式命名。


. 函式註釋


系統自動生成的函式,如滑鼠動作附應函式等,不必太多的註釋和解釋;


對于自行編寫的函式,若是系統關鍵函式,則必須在函式實現部分的上方標明該函式的訊息,格式如下︰


/**
* 函式名︰
* 編寫者︰
* 參考資料︰
* 功  能︰
* 輸入參數︰
* 輸出參數︰
* 備  注︰
*/


希望盡量遵循以上格式。



五、符號風格


. 總體要求


對于各種符號的定義,都有一個共通點,就是應該使用有實際意義的英文單詞或英文單詞的縮寫,不要使用簡單但沒有意義的字串,儘可能不使用阿拉伯數字,
更切忌使用中文拼音的首字母。如這樣的名稱是不提倡的︰Value1,Value2,Value3,Value4 …。


例如︰
file(文件),code(編號),data(數據),pagepoint(頁面指針), faxcode(傳真號) ,address(位址),bank(開戶銀行),……


. 變數名稱


a. 變數名前綴的約定


變數類型    前綴   示例
integer     int    intCount
byte        byt    bytMove
short       sht    shtResult
long        lng    lngTotal
float       flt    fltAverage
double      dbl    dblTolerangce
boolean     bln    blnIsover
Char        chr    chrInput
Array       arr    arrData


變數名一般要有一定的表達義,變數名中的每一個單詞的第一個字母都要大寫出(除去第一個單詞外)


b. 描述性變數名和過程名︰


變數名或過程名的主體使用大小寫混合格式並且盡量完整地描述其目的,另外過程名應以動詞開始如︰InitNameArray ,CloseDialog


. 對象名的約定︰


對象名的前綴約定︰


對象類型    前綴
Button      btn
Canvas      cvs
CheckBox    chk
Image       img
Label       lbl
List        lst
Choice      chc
Dialog      dlg
Event       evt
Frame       frm
Menu        menu
Panel       pnl
TextArea    txa
TextField   txf


. Package 的命名


Package 的名字應該都是由一個小寫單詞組成。


. Class 的命名


Class 的名字必須由一個或數個能表達該類的意思的大寫字母開頭而其它字母都小寫的單詞或縮寫組成,這樣能使這個 Class 的名稱能更容易被理解。


. Class 變數的命名


變數的名字必須用一個小寫字母開頭。后面的單詞用大寫字母開頭。對于類的成員變數,在對其標識符命名時,要加上代表member(成員)的前綴m_。
例如一個標識符為m_dwFlag,則它表示的變數是一個類型為雙字的成員變數,它是代表一個標誌。


. Static Final 變數的命名


Static Final 變數的名字應該都大寫,並且指出完整含義。


. 參數的命名


參數的名字必須和變數的命名規範一致。


. 數組的命名


數組應該總是用下面的模式來命名︰
byte[] buffer; 
 
而不是︰
byte buffer[];


. 方法的參數
 
使用有意義的參數命名,如果可能的話,使用和要賦值的字段一樣的名字︰


SetCounter(int size)
{
 this.size = size;
}


. 神祕的數


首先要說什麼是神祕的數。我們在程式裡經常會用到一些量,它是有特定的含義的。
例如,現下我們寫一個薪金統計程式,公司員工有50人,我們在程式裡就會用50這個數去進行各種各樣的運算。在這裡,50就是"神祕的數"。
為什麼稱它為神祕呢?因為別的程式員在程式裡看到50這個數,不知道它的含義,只能靠猜了。


在程式裡出現"神祕的數"會降低程式的可讀性,應該盡量避免。避免的方法是把神祕的數定義為一個常量。
注意這個常量的命名應該能表達該數的意義,並且應該全部大寫,以與對應于變數的標識符區別開來。
例如上面50這個數,我們可以定義為一個名為NUMOFEMPLOYEES的常量來代替。這樣,別的程式員在讀程式的時候就可以容易理解了。



 

    全站熱搜

    立你斯 發表在 痞客邦 留言(0) 人氣()