程式碼撰寫風格指南 Coding Style Guide

蔡神(tsaiwn@ydu.edu.tw)編譯整理

參考資料(References) :

這份文件中所建議的程式碼撰寫慣例(convention)主要參考下列文件(另外參考網路上一些文章):

  • Oracle(Sun)公佈的官方文件:Code Conventions for the Java Programming Language
  • 點這查看 Java 變數與函數等的命名慣例

    點這看看關於 Flash 變數與實體名稱的命名建議
    注意:
        如果你是微軟的C#的愛好者, 請注意微軟 C# 的撰寫慣例有點不太一樣,
    請點這參考 C# coding Standrad document.
    

    1. 簡介

    1.1 為何需要程式碼撰寫標準(Coding standard)?

    1.2 致謝(Acknowledgments)

        本文主要參考 Sun公司(已經被Oracle公司併購)之Java語言規格書( in the Java Language Specification)內所規範的程式碼撰寫慣例(coding standards; coding convention), from Sun Microsystems, Inc. Major contributions are from 主要貢獻者包括以下諸位先進: Peter King, Patrick Naughton, Mike DeMoney, Jonni Kanerva, Kathy Walrath, and Scott Hommel.

    2. 檔案名稱 (File Names)

    Java Source 程式原始碼:*.java

    Java bytecode:*.class

    3. 檔案組織 (File Organization)

    一般慣例:

    3.1 Java 原始碼 (Java Source Files)

    Java 原始碼檔案的組成分子,依照出現的順序排列為:

    3.1.1 起始註解 (Beginning Comments)

    每個 Java 程式碼檔案的開頭都應該有類似 C 語言風格( C-style )的註解,參考下列範例:

    英文範例:

    /*
     * Description
     *
     *   A brief description of the class/interface.
     *
     * History
     *
     *   yyyy-mm-dd Author        
     *              What has been changed.
     *
     * Copyright notice
     */
    中文範例:
    /*
     * 說明
     *
     *   簡短描述這個類別/介面(Class/Interface)。
     *
     * 修改歷史
     *
     *   yyyy-mm-dd 作者姓名
     *              修改了哪些東西。
     *
     * 版權聲明
     */

    3.1.2 套件與匯入敘述 (Package and Import Statements)

          如果要寫 package (套件)敘述(建議要寫), 則必須是註解之外的第一句, ( Android programming 甚至規定一定要寫, 且至少要有兩個英文單字用點隔開, 例如 package ggg.yyy; )注意, 套件必須忠實反應目錄結構, 也就是說如果你宣告了package ggg.yyy; 那就必須把所有的檔案放到目錄 ggg\yyy之下。
       接著要寫的是 import 敘述, 這是為了讓編譯器知道程式碼中寫的類別是在哪個套件(目錄), 並不是真的會匯入(import)資料! 嚴格說是規範命名空間(naming space), 所以像 C++ 與 C# 是用 using namespace 或 using 的寫法。

    3.1.3 類別和介面宣告 (Class and Interface Declarations)

    類別和介面各個組成分子,依照應該出現的順序排列如下:
    順序 項目 備註
    1 類別/介面(class/interface)的註解 請使用C語言形式的註解如 /* ... */
    2 class 或 interface 敘述 一個檔案可以含有多個class與Interface, 但最多只可以有一個冠上 public , 且冠上 public 的那個必須與檔案同名
    3 類別或介面的實作註解(有需要才寫) 就是程式碼敘述有必要說明時寫啦!
    4 類別變數(宣告為 static 的變數) 依照 public,protected, 和 private 的順序宣告。
    5 Instance 變數(實體變數; 案例變數) 依照 public,protected, 和 private 的順序宣告。
    6 建構子(constructor) 名稱大小寫都須與類別名稱相同
    7 finalize( ) 注意這與 destructor 解構子略有不同!
    8 方法(Method; 函數; function) 相關功能的方法應該擺在一起,而不是以 public 或 private 存取範圍來區分。這樣安排的目的是為了增加程式的可讀性。

    4. 縮排(Indentation)

         建議每次縮排為縮入 4 個空格,並且使用 Tab 字符(character; 字元)來縮排, 亦即建議修改編輯器的設定,將 TAB 字符以 4 個空白字元來顯示 (大部分的文書編輯器都有提供這類功能把TAB換為最多跳4個空白), 如果你的編輯器不支援這替換功能,那只好自己手動敲入空白字符對齊囉。 不過也有人不建議更改 TAB 的設定, 就是讓 TAB 仍維持最多跳8個空白, 但你每次縮排用4個空白 !
    之所以建議每次縮四個空格是因為如果每次縮八個空格那縮個幾次就跳到很右邊剩下沒幾個字可以寫:-)

    4.1 每列長度與邊界 (Line Length)

    每列敘述不要超過 80 個字符(character; 字元),文件內的範例程式則建議在 70 個字元以下。

    4.2 折行(Wrapping Lines)

    程式碼若太長會超出邊界時,可採取下列方式折行:

    範例:

    // 折行後,跟前一道敘述中同階層的表示式對齊。
    var = someMethod1(longExpression1,
                      someMethod2(longExpression2,
                                  longExpression3));
    
    // 折行後原則上最多縮排兩次,以避免過度深層的縮排寫到太右邊
    var = someMethod(longExpression1, longExpression2, longExpression3,
        longExpression4, longExpression5);  
    
    // 在外層折行,正確。
    longName1 = longName2 * (longName3 + longName4 - longName5)
                + 4 * longname6;
    
    // 在內層折行,很不好!應儘量避免
    longName1 = longName2 * (longName3 + longName4
                - longName5) + 4 * longname6;

    if ... else 的折行規則也是用兩次縮排,若只用一次縮排,if 敘述折行後會跟 if 區塊內的敘述對齊,使得不易辨識區塊主體,例如:

    // 錯誤示範
    if ((condition1 && condition2)
       || (condition3 && condition4)
       ||!(condition5 && condition6)) {   
       doSomethingAboutIt();              
    } 
    
    // 正確寫法
    if ((condition1 && condition2)
            || (condition3 && condition4)
            ||!(condition5 && condition6)) {
        doSomethingAboutIt();
    } 
    
    // 若只縮排一次,則條件式和區塊主體之間要空一行
    if ((condition1 && condition2) 
        || (condition3 && condition4)
        ||!(condition5 && condition6)) {
    
        doSomethingAboutIt();
    } 

    5. 註解 (Comments)

    一般慣例:

    Java 的註解主要分成兩種:

    1. 實作註解(implementation comments),寫法跟 C++ 的註解一樣,有 /*...*/ 多行註解和 // 單行註解這兩種型式。
    2. 文件註解(documentation comments),是 Java 特有的註解型式,寫法是 /**...*/,這類註解可以被 javadoc 工具讀取並產生 HTML 說明文件。

    實作註解主要是用來說明程式碼,文件註解則用來描述程式碼的規格。

    註:如果程式當中到處都是註解,可能意味著程式碼的品質較差,當然這並不是要你把註解拿掉或乾脆不寫註解,而是希望你注意到,當你覺得若不寫這麼多冗長的註解就很難讓人了解程式碼時,你可能要考慮用更好的方式改寫這段程式碼。

    5.1 實作註解(implementation comments)

    5.1.1 區塊註解(Block Comments; 多行註解)

    區塊註解可以用在檔案標頭、每個函式之前、或程式碼中的任何地方。區塊註解的前面應該要有一列空白。例如:

    someMethod();
    
    /*
     * Here is a block comment.
     */
    hello();

    不要用很多 * 把註解框起來,像下面這樣:(不過有些人喜歡這樣:-)

    /*********************
     *                                *
     *  這是個錯誤示範           *
     *                                *
     *********************/

    5.1.2 單行註解 (Single-Line Comments; 單列註解)

    比較短的註解可以使用單行註解,單行註解可以用 /*...*/ 或 // 兩種寫法,建議使用後者,
    因為如果你使用 /*...*/ 這種 C 格式的註解,那之後想把許多列一次註解掉就變很麻煩, 這是因為 註解 沒有巢狀(nested)的概念,不像括號之內可以有另一對括號。 連續的 // 單列註解也常被用來將一段程式碼註解掉(comment out),參考下面的範例:

    if (foo > 1) {
    
      // Do a double-flip. 注意前面要空一行
      ...
    }
    else {
      return false;          // 寫在這裡的叫做 end-of-line comments
    }
    //if (bar > 1) {
    //
    //  // Do a triple-flip.
    //  ...
    //}
    //else {
    //  return false;
    //}

         不過這種連續用//單列註解掉的程式碼如果之後要恢復就比較麻煩(廢話)!

    5.1.3 尾隨註解 (Trailing Comments) (蔡神註: 不建議使用這, 建議改用5.1.4的//結尾註解)

    非常短的註解可以在他們描述的程式碼同一行出現, 但是應該離開足夠的距離來讓他們與敘述分隔。 如果有超過一個短註解在大區塊程式碼中出現, 那他們應該被縮排到同一個 tab 設定。

    這裡是一個 Java 程式碼中的尾隨註解範例:
    
        if (a == 2) {
            return TRUE;               /* 特別狀況  */ 
        } else {
            return isPrime(a);         /* 只在 a 為奇數時有作用 */ 
        }
    
    

    5.1.4 結尾註解 (End-Of-Line Comments) (蔡神註: 建議用這結尾註解)

    使用連續兩斜線(C++風格註解) // 的註解可以註解一整行或是行的一部分。 蔡神強烈建議儘量使用這種取代前面5.1.3說的在一列尾巴使用C風格註解!

    這裡是一個 Java 程式碼中的結尾註解範例:
    
        if (a == 2) {
            return TRUE;               // 特別狀況  
        } else {
            return isPrime(a);         // 只在 a 為奇數時有作用 
        }
    
    
    C++風格的 // 結尾註解建議不要用在連貫的多行文件說明註解中;但是它可以用在
    連貫的多行中來註解掉一區塊的程式碼(前面說過這樣之後要恢復程式碼比較麻煩)。
    下列是這種形式的範例:
    
        if ( foo > 1) {
               
            // 做出雙空翻。
            // ...
        }
        else {
             return false;    // 在這裡解釋為甚麼 
        } 
        // if (bar > 1) {
        //
        //      // 做三重空翻。
        //      ...
        //}
        //else{
        //    return false;
        //}  
    
    

    5.2 文件註解 (Documentation Comments)

    注意: 請參考 後面 11.1 "Java 原始碼檔案範例"

    進一步的細節請看包含 doc 註解標籤(@return, @param, @see) 資訊的
      "How to Write Doc Comments for JavaDoc":
      
           http://java.sun.com/products/jdk/javadoc/writingdoccomments.html
     
      進一步的 doc 註解和 javadoc 細節,請看 javadoc 首頁:
      
           http://java.sun.com/products/jdk/javadoc/
     
      doc 註解描述了 Java 類別, 介面, 建構子(constructor),方法(method; 就是函數啦),和欄位(field)。
      每一個 doc 註解都設定成放在 /**...*/ 分隔子中,每一個類別,介面或是函數成員都應該有一個註解。
      這些註解應該要在宣告的前面出現。
     
        /**
         * 這個 Example 類別提供了 ...
         */
        public class Exampke { ...
    
    

    注意頂層的類別和介面並沒有縮排,而他們的成員有。這類別和介面的 doc 註解 的第一行(/**)是沒有縮排的;隨後的 doc 註解行都有 1 個縮排的空格 ( 垂直 對齊星號)。成員 (包括建構子) 的第一個 doc 註解行則有 4 個空白, 以及之後的則要有五個空白。

    如果你需要給予不適合出現在文件中的關於類別,介面,變數,或是方法的資訊, 建議使用馬上接在宣告之後的區塊註解(見 5.1.1 小節) 或是單行註解(見 5.1.2 小節)來實作。 例如,關於類別實作的細節應該在跟著類別敘述的區塊註解實作中, 而不是寫在類別的 doc 文件註解中。

    注意, 文件註解 Doc comments 不應該被放在方法或是建構子的內部定義區塊中,因為 Java 會將文件註解 和註解後的第一個宣告關聯起來。(蔡神註: 就是使用 javadoc 工具產生HTML網頁文件時會這樣做!)

    6. 宣告 (Declaration)

    6.1 一行一個宣告 (Number Per Line)

    建議一行(一列)只寫一個宣告,這樣有利於撰寫註解,例如下面的寫法:

    int level; // Indentation level
    int size;  // Size of table

    比這種寫法好:

    int level, size;
    最糟糕的是把不同用途的東西擺在同一行宣告,例如:
    int foo, fooarray[];  // WRONG!

    註:以上的寫法都是用一個空白字元來分隔型態和變數名稱,另一種可以接受的寫法是用 TAB 字符(character; 字元),例如:

    int	 level;        // Indentation level
    int	 size;	        // Size of table
    Object	 currentEntry; // Currently selected table entry

    6.2 初始化 (Initialization)

    儘量在宣告變數時就設定初始值。

    6.3 宣告的位置 (Placement)

    儘管 Java 允許你在任何地方宣告變數,把宣告集中在程式區塊一開始的地方(由 {...} 包住的稱為程式區塊)會比較清楚。參考下面的範例:

    void myMethod() {
      int int1 = 0;       // 正確
    
      if (condition) {
        int int2 = 0;   // 正確
        ...
      }
    
      int int3 = 0;       // 錯誤,應該跟 int1 的宣告在一起
    }

    唯一的例外是 for 迴圈的索引變數(index variable),它可以直接宣告在 for 敘述裡面,例如:

    for (int i = 0; i < maxLoops; i++) {
      ... 
    }

    注意不要讓區域變數蓋過外層的變數,例如:

    int count;
    ...
    myMethod() {
      if (condition) {
        int count; // 錯誤! 容易讓人混淆,不易Debug除錯
        ...
      }
      ...
    }

    6.4 類別和介面的宣告 (Class and Interface Declarations)

    在撰寫類別和介面時,應遵守下列規則:

    範例:

    class Sample extends Object {
      int ivar1;
      int ivar2;
      Sample(int i, int j) {
        ivar1 = i;
        ivar2 = j;
      }
      int emptyMethod( ) { }
      ...
    }

    7. 敘述(Statements; 指述; 指令的描述)

    7.1 簡單敘述 (Simple Statements)

    一行只能寫一個敘述,例如:

    argv++; // 正確
    argc++; // 正確
    argv++; argc--; // 錯誤!

    7.2 複合敘述 (Compound Statements)

    所謂的複合敘述,指的就是以大括號 '{...}' 包住的敘述,通用的規則是:

    7.3 return 敘述 (return Statements)

    單純的傳回值不要加括號,例如:

    return;
    return myDisk.size();

    若傳回值使用了較複雜的敘述,可以使用括號,例如:

    return (size ? size : defaultSize);

    7.4 if, if-else, if else-if else 敘述

    if-else 敘述應依照下列格式撰寫:

    if ( condition) {
      statements;
    }
    if ( condition) {
      statements;
    } else {
      statements;
    }
    if ( condition) {
      statements;
    } 
    else if ( condition) { // else 也可以自己獨立一行
      statements;
    } 
    else {   
      statements;
    }

    注意Note:不管單行還是多行敘述,都應該要使用大括號比較好(別偷懶!)

    7.5 for 敘述

    for 敘述應依照下列格式撰寫 :

    for (initialization; condition繼續做的條件; update更新變數或索引) {
      statements;
    }

    空的 for 敘述:

    for (initialization; condition; update);

    就是沒有身體(Loop body)的 for 敘述, 通常是利用 initialization 以及 update 部分順便做事, 因為由兩個分號所隔開的這initialization; condition; update三句都可以各自 寫很多句子用逗號(,)隔開; 但因為這會使得別人不容易看懂, 建議在各部份的句子用到的變數不要超過三個。

    7.6 while 敘述

    while 敘述應依照下列格式撰寫 :

    while (condition) {
      statements;
    }

    空的 while 敘述:

    while (condition);

    7.7 do-while 敘述

    do-while 敘述應依照下列格式撰寫 :

    do {
      statements;
    } while (conditions);

    7.8 switch 敘述

    switch 敘述應依照下列格式撰寫 :

    switch (condition) {
    case ABC:  // case 不需要縮排
      statements;
      // 往下繼續執行 (falling through; 穿越)
      // 因為沒有寫 break;  
    case DEF:
      statements;
      break;
    case XYZ:
      statements;
      break;
    default:
      statements;
      break;  // 若 default 是最後一個 case,這裡的 break 可不寫。
    }

    當一個 case 裡面沒有寫 break 時,程式會繼續往下執行,這功能稱作穿越(falling through), 這時必須在這個 case 往下執行的地方加上註解,表示你是故意的不是寫錯或忘記寫! 就像上面的範例一樣,這樣可以避免粗心的程式設計師誤解程式流程。

    7.9 try-catch 敘述

    try-catch 敘述應依照下列格式撰寫 :

    try {
      statements;
    } 
    catch (ExceptionClass e) {
      statements;
    }
    try {
      statements;
    } 
    catch (ExceptionClass e) {
      statements;
    } 
    finally {
      statements;
    }

    8. 空白 (White Space; 廣義空白)

    8.1 空白行 (Blank Lines)

    適當地加入空白行可以區分程式段落,提高可讀性。

    以下情況應該加入兩行空白行:

    以下情況應該加入一行空白行:

    8.2 空白字元 (Blank Spaces)

    以下情況應該使用空白字元(建議至少放一個空格):

    while (true) {
      ...
    }
    a += c + d;
    a = (a + b) / (c * d);
    while (d++ = s++) {
      n++;
    }
    prints("size is " + foo + "\n");
    for (expr1; expr2; expr3)
    myMethod((byte) aNum, (Object) x);
    myMethod((int) (cp + 5), ((int) (i + 3)) + 1);

    9. 命名慣例 (Naming Conventions)

    9.1 Java 命名慣例 (Java naming convention)

    命名慣例讓程式更容易被理解和閱讀。
    它們也可以給予關於識別子功能的資訊,例如, 一看名稱就知道是否為常數,套件,或是類別,這可以在瞭解程式碼時很有幫助。

    一般建議:

    • 使用完整的、能夠望文生義的英文。
    • 使用跟該領域相關的術語。
    • 大小寫混合使用,以增加可讀性。
    • 名稱儘量不要超過 15 個字符(character; 字元)。
    • 不要只用大小寫的差異來辨別兩個變數名稱,這樣容易造成混淆。
    項目 命名慣例 範例
    Packages
    套件
    套件(package)名稱應該用全部小寫的ASCII字母, 而且應該是top-level 的網域名稱之一(目前有com,edu,gov,mil,net,org 或者是由1981年ISO Standard 3166所定義由兩個英文字母來代表國家的識別碼。) 為了避免和其他套件名稱衝突, 一般會將公司或組織的 internet 網域名稱(Domain name)順序顛倒過來,再加上套件名稱,不用把網域名稱的每個部分都加進去,用一個或兩個就行了。
      注意 Android Java programming 規定套件名稱至少要兩個英文單字, 例如 com.google 是正確套件名稱; 還要注意, 要上傳到 Google Play(以前的Android Market)的每個APP程式的package name必須是唯一。
    java.awt,
    com.oracle.utility
    com.google.android.v4
    flash.events
    flash.display
    Class
    類別
    類別名稱應該是名詞,類別名稱可混合大小寫,但類別名稱開頭第一個字要大寫。 類別名要簡單容易描述,儘量少用縮寫或略稱,除非是URL ,HTML等廣泛使用的字。 Clock, Cake, MovieClip
    Interface
    介面
    跟類別的命名規則完全相同,使用完整的英文,介面名稱的每個單字的第一個字母都大寫,其餘小寫。 如果可能的話,儘量使用形容詞,也就是 'able','ible' 等字尾的名稱(不是絕對必要)。 Runnable, Contactable, Clonable
    Compilation unit files
    檔案命名
    以類別(或介面)名稱作為主檔名,附屬檔名為小寫的'.java'。 Clock.java, MouseEvent.java

    Member functions
    成員函數
    或稱方法(Method)
    函數(function, 函式)又稱方法(Method), 使用完整的英文, 最好是用動詞命名,用小寫字母開頭,如果是多個英文單字(word)連起來, 第一個單字的第一個字母小寫,其餘的單字的第一個字母大寫,就是說斷字的地方字母大寫
    注意: 建構子Constructor 這函數比較特別, 其名稱以及大小寫必須與類別名稱完全相同。
    openFile( ), addChild( ),
    getMoney( )
    Setter 成員函式 把要存取的欄位名稱前面冠上 'set'。 setFirstName(),
    setLastName()
    Getter 成員函式 把要存取的欄位名稱前面冠上 'get'。 getFirstName(),
    getLastName()
    傳回布林型態的 getter 成員函式 開頭一律冠上 'is'。 isDead(), isString(), isFailed()

    Fields/properties
    欄位/屬性
    所謂欄位或屬性(property, attribute)又稱 成員資料(member data), 包括變數與常數, 請參考以下變數與常數命名。
    Variables
    變數
    變數名稱不應該以底線(_)或dollar sign($)開頭,雖然那樣還是正確但不好。 變數名稱要短且有意義, 除了臨時變數之外,要儘量避免使用一個字元的變數名稱。 若是臨時變數, 一般是用i, j, k, m, n來代表整數,x, y, z 代表實數, c, d 代表文字符號(character; 字符或稱字元)。 int age;
    int myMoney;
    double delta;
    int i, k, n;
    Parameters
    參數
    參數就是寫在函數名稱 之後小括號內的 變數, 原則上命名方式與變數相同; 使用完整的英文來描述傳遞的變數/物件, 可在前面冠上 'a' 或 'an',不管用哪種方式,最重要的是定好後大家就要遵守它。 customer, account 或
    aCustomer, anAccount
    Exceptions
    異常或例外
    通常以小寫字母 'e' 代表異常物件變數。 e 或 ex
    Final static fields (consants)
    常數
    全部使用大寫英文字母,每個單字之間用底線分隔。 NUMBER_STUDENT,
    MOUSE_OVER, ENTER_FRAME
    Loop counters
    迴圈計數器
    通常以 i, j, k 或 counter 來命名。 i, j, k, cnt, counter
    Local variables
    區域變數
    或稱局部變數
    原則上區域變數使用完整的英文,第一個單字(word)的第一個字母小寫,其餘的單字的第一個字母大寫。
    注意:應避免和類別的欄位名稱相同,以免產生混淆,例如,你有一個欄位名稱是 'firstName',那麼在成員函式中的區域變數就不要取相同的名稱。
    totalMoney, tempSum, tmpString
    
    註:
        區域變數(Local variable; 局部變數; 函數內的變數)的命名可以稍有彈性,
        對於比較不重要的變數,可以採取如 i, j, k, m, n, tmp 等簡短的命名方式,
        但請特別注意,不要隨意亂用,原則上仍應該儘量以完整的英文來命名。
        下表列出一些建議的臨時變數命名:
    
    變數類型 建議的命名慣例
    char 字符(字元) c 或 ch
    String 字串 str 或 s 或 tmpStr
    代表有幾個 n 或 k
    length 長度 len
    offset 位移整數 off
    一般 int 整數 i 或 k 或 m 或 n
    float 實數 f 或 x 或 y
    double 實數 d 或 x 或 y
    Object 物件 o 或 obj
    點這看關於Flash ActionScript 3.0 建議的元件實體(symbol instance)之實體名稱
     在字尾(suffix, postfix)補上可以代表元件類別的表示方式後面會列表讓大家參考

    9.2 縮寫(Abbrivation)與頭字語(Acronym)的大小寫建議

    
        當識別字(identifier)名稱中包含縮寫字與頭字語如 ID 或 ANSI 時,一律採用大寫,
    尤其是頭字語(Acronym; 就是幾個單字的第一字母組成的, 例如 IBM 代表 International Big Mouth,
    又如 ROC代表 Republic Of China 或 Republic Of Confusion)更該用全大寫,
    但是有個例外, 就是當縮寫字是變數或函數名稱的第一個單字時, 仍然該用小寫, 例如:
       int rocStartYear = 1912;  // 民國元年等於西元 1912
    
    
     Top

    10. 程式設計習慣(Programming Practices)

    
       類別設計的最佳原則是:
           變數儘量藏起來(用 private),     
           函數(方法)儘量公開(用 public)!  
    
    

    10.1 提供實體變數和類別變數的權限 (Providing Access to Instance and Class Variables)

    沒有好理由的話,不要讓任何的實體變數或是類別變數是 public 的。 通常,實體變數不需要被直接的設定或是獲得 -- 通常是作為方法呼叫的邊際效應。

    一個適當的 public 實體變數的例子是當這個類別是一個沒有行為的基本的資料結構時。 換句話說,如果你可能會使用 struct 來代替類別的話 (如果 Java 支援 struct 的話, 但Java不支援struct) ,那讓類別的實體變數是 public 就是適當的。

    10.2 引用類別變數和方法 (Referring to Class Variables and Methods)

    避免使用物件來存取類別(static)變數和方法。使用類別名稱來代替。 例如:

     
        classMethod();           // OK
        AClass.classMethod();    // OK
        anObject.classMethod();  // 避免 ! 
    

    10.3 常數 (Constants)

    會出現在 for 迴圈中當作計數值的數值常數 (literals; 字面常數) , 除了 -1,0,和 1 之外,不應該直接編寫數值, 應該事先用 public static final 定義符號常數。

    10.4 變數指定值 (Variable Assignments)

    避免在單一敘述中指定好幾個變數為同一個值。
    那會不容易閱讀。例如:
      
        fooBar.fChar = barFoo.lchar = 'c';  // 避免! 不要耍帥 !
     
      不要在可能很容易會跟相等運算子(==)搞混的地方使用指定運算子。例如:
      
        if (c++ = d++) {        // 避免! ( Java 不允許; 但 C/C++可以)
            ...
        }
     
      應該寫成
      
        if ((c++ = d++) != 0) {  // 正確
            ...
        }
     
      不要為了改善執行效率而使用嵌入式的指定(embedded assignments)。
      那是編譯器的工作。例如:
      
        d = ( a = b + c) + r;      // 避免!
     
      應該寫成
      
        a = b + c;
        d = a + r;
    
    

    10.5 其他慣例 (Miscellaneous Practices)

    10.5.1 小括號 (Parentheses)

    在表示式(expression; 運算式)中包含了混和的運算子(operator; 運算符號; 操作子)時, 使用大量的小括號來避免優先權的問題是一個不錯的作法。 即使運算子的優先權對你來說看來很清楚,對別人來說可能不是如此 -- 你不應該假設其他的程式設計師對優先權的瞭解跟你一樣好。

        if (a == b && c == d)       // 避免!
        if ((a == b) && (c == d))   // 應該這樣使用才不會被誤會
    

    10.5.2 回傳值 (Returning Values)

      試著讓你程式的架構符合意圖。例如:
     
        if (booleanExpression) {
            return true;
        } else {
            return false;
        }
     
      應該以下列取代
     
        return booleanExpression;
     
      相同的,
     
        if (條件) {
            return x;
        }
        return y;
     
      應該寫成這樣
     
        return (條件 ? x : y);
    
    

    10.5.3 在條件運算子中 "?" 之前的表示式 (Expressions before `?' in the Conditional Operator)

    如果在 ?: 運算子的 ? 之前出現的表示式中包含了二元運算子, 那你應該用小括號將之括起來。例如:
    (x >= 0) ? x : -x;

    10.5.4 特別註解 (Special Comments)

    在註解中使用 XXX 來標出一些假的但是仍有用的東西。 使用 FIXME 來標示出一些有問題而且壞掉的東西,表示尚待修正。

    
    
    
    

    11. Java 程式碼範例(JJava Source File Example)

    下列範例顯示了如何格式化一個包含單一 public 類別的 Java 原始碼檔案。 介面也以相似的方法格式化。 更多的資訊請參閱 3.1.3 小節的 "class 和 interface 宣告" 和 5.2 小節的 "文件註解" 。

    
    /*
     * @(#)Blah.java        1.82 99/03/18
     *
     * Copyright (c) 1994-1999 Sun Microsystems, Inc.
     * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
     * All rights reserved.
     *
     * This software is the confidential and proprietary information of Sun
     * Microsystems, Inc. ("Confidential Information").  You shall not
     * disclose such Confidential Information and shall use it only in
     * accordance with the terms of the license agreement you entered into
     * with Sun.
     */
    
    
    package java.blah;
    
    import java.blah.blahdy.BlahBlah;
    
    /**
     * Class description goes here.
     *
     * @version 	1.82 18 Mar 1999
     * @author 	Firstname Lastname
     */
    public class Blah extends SomeClass {
      /* A class implementation comment can go here. */
    
      /** classVar1 documentation comment */
      public static int classVar1;
    
      /** 
       * classVar2 documentation comment that happens to be
       * more than one line long
       */
      private static Object classVar2;
    
      /** instanceVar1 documentation comment */
      public Object instanceVar1;
    
      /** instanceVar2 documentation comment */
      protected int instanceVar2;
    
      /** instanceVar3 documentation comment */
      private Object[] instanceVar3;
    
      /** 
       * ...constructor Blah documentation comment...
       */
      public Blah() {
        // ...implementation goes here...
      }
    
      /**
       * ...method doSomething documentation comment...
       */
      public void doSomething() {
        // ...implementation goes here... 
      }
    
      /**
       * ...method doSomethingElse documentation comment...
       * @param someParam description
       */
      public void doSomethingElse(Object someParam) {
        // ...implementation goes here... 
      }
    }
    
    
    
    

    12. 關於 Flash ActionScript 的變數與物件命名

    
    
        1020請脫下褲子!
    2010年12月2日下午在台北監獄你可以聽到這句很奇怪的話 :-)
    因為當時阿扁到達台北監獄後獄方給他1020的受刑人編號,獄方依慣例要檢查屁股洞內有沒藏毒品!
    從此,在北監“1020”取代了陳水扁。
    
        阿這跟Flash有啥關係? 當然有關係!
    Flash 影片與程式內有很多情況也是使用編號, 舞台上的物件都有編號, 只是很少用到; 影格都有編號,
    例如 gotoAndPlay(23); 意思是跳到整體的第 23 個影格(frame), 它可能是第二個場景的第5影格!
    如果第二個場景名稱是"SceneB"(注意大小寫以及空格也不可亂寫),
    則也可以寫成  gotoAndPlay(5, "SceneB"); 
    這樣萬一第一個場景增加或刪除影格仍可跳到正確的影格, 但是, 如果第二場景一開始多了一些影格,
    則這第二句仍會跳到不是我們要的影格, 所以我們也可以給該影格取一個名稱,
    例如 "開門" (有命名的影格上會有一個紅色小旗子), 然後可以寫
        gotoAndPlay("開門", "SceneB"); 
    看到沒, 編號與命名各有好處!
    
        在舞台上的物件可能是你直接畫的, 那無法命名, 不能從程式碼中控制,
    你必須先轉為元件(Symbol), 此時元件會被放入元件庫, 
    原先在舞台上的則會自動被轉為該元件的一個實體(Symbol instance; 案例; 分身), 
    可以不必給實體名稱, 但如果你要從程式碼中控制它, 則必須給它一個實體名稱, 
    它會對應到程式碼中的一個變數, 這等下再來討論。
    
        元件庫內的元件都必須有名稱, 但是因為程式碼執行時不會用到元件庫名稱, 所以你可以
    使用中文給元件庫內的元件命名
    
        雖然場景名稱與影格名稱在程式碼中也可能用到, 
    但因為都是被當作字串的內容, 至於圖層的名稱在程式碼中不會用到, 
    所以, 場景、圖層、影格的名稱都可以取中文不會有問題。
    
    

    變數命名慣例(Variable naming convention)

    Flash 的 ActionScript3.0 採用 Java 語言的命名慣例(naming convention), 雖然命名慣例只是個建議, 但是良好的命名原則可讓你與別的程式設計師容易溝通且不會產生誤會! 例如, 如果你遵守大家的慣例, 就不會把 gotoAndPlay 寫錯為 GotoAndPlaygotoandplay 了! 註: 微軟 C-Sharp( C# )的命名習慣不一樣! Delphi (視覺化的Pascal)命名習慣也不同! 以下是 Java 語言推薦的命名習慣, AS3 採用 Java 語言的命名習慣。 就是: (a)套件(package)名稱一律用小寫, 反應其在磁碟的目錄路徑結構; 例如 flash.events 套件實質意義上是把相關的類別放在一個目錄內 (b)類別(class)名稱的第一個字母一律用大寫字母, 例如 Cat Clock 如果有兩個英文單字組起來, 斷字處用大寫, 例如 DisplayObject (c)物件(或稱變數)名稱一律小寫開頭, 例如 myCatmyClock 又如 var cat: Cat = new Cat( ); 意思是創建一個 Cat 類別實體, 命名為 cat 如果有兩個英文單字組起來, 斷字處用大寫, 例如 MovieClipdisplayObject 請注意, displayObjectDisplayObject 第一個字母不一樣喔! (d)屬性(property, 或稱欄位)如果是可改變的(此時也可稱變數), 命名慣例與物件相同; 例如 width height 又如 var length: int = stage.width; (e)屬性如果是唯讀或說不准改變的, 那就是常數(constant), 這時習慣是全部用大寫字母, 例如, CLICK DISPLAYING 如果有兩個英文單字組起來, 斷字之處則用底線號_連接, 方便看出原英文單字; 例如 ENTER_FRAME 以及 MOUSE_CLICK 後者的全名是 flash.events.MouseEvent.MOUSE_CLICK 其實質意義就是 flash.events 這套件(目錄)內的類別 MouseEvent 裡面定義的 MOUSE_CLICK 這常數。 (f)方法(或稱函數)名稱也是一律小寫開頭, 例如 getMoney( ) 注意, 方法(函數)名稱的後面有小括號, 裡面可以有0個到很多個參數。 參數(給方稱 argument, 受方稱 parameter)顧名思義就是叫用者給被叫者參考使用的資料。 例外: 建構子(constructor)函數因規定名稱必須與類別名稱(class name)完全相同, 所以其第一個字母也是用大寫字母(除非你把類別名稱故意取小寫字母開頭!)。 關於程式寫作慣例: 請看http://www.oracle.com/technetwork/java/javase/documentation/codeconvtoc-136057.html 或是點這裡看翻譯的中文版
    
    
          

    關於物件的實體名稱

    前面提到元件庫內的每個元件當然有名稱, 元件庫內可以使用中文命名不會有問題, 把元件拖到場景的舞台上會自動產生一份元件實體(symbol instances; 案例), 該實體物件可以不必命名,但是,如果希望能夠在程式碼(ActionScript)中控制該實體物件, ,就要幫該實體物件設定實體名稱,這時不可以使用中文名稱,且最好遵守大家常用的慣例(convention)! 簡單來說就是要幫這個元件實體(instance; 案例)宣告一個變數,步驟如下:

    1. 將建立好的影片片段(MovieClip)或其他元件(Symbol),拖曳到舞台上。
    2. 使用(選取工具),點選舞台上的該物件, 到『屬性面板』上實體名稱的格子填入英文字母開頭的名稱即可。
    3. 除了場景、圖層、影格的名稱可以取中文, 舞台上物件的實體名稱千萬不要取中文。
            再次提醒, 既然實體名稱對應到程式碼中的變數, 建議遵守(參考Java語言)變數命名的原則!
        請注意, 元件庫中的元件(Symbol)可以拖拉出很多個分身, 每個分身的實體名稱是各自命名。
        還有, 圖像元件的分身(實體)在舞台上是不可以命名的, 你可以先轉為影片片段元件。

    設定好物件的實體名稱後,在ActionScript程式碼中就可以用該名稱來使用該元件實體了。 在定義實體名稱時雖可隨便命名,但建議在命名時加入適當的後置名稱(postfix), 例如若是影片片段(MoveClip),尾巴建議加上 _mc, 如果那是與球有關的, 就把實體名稱取為 ball_mc, 命名時若取適當結尾,不但方便我們識別, 寫程式碼的時候Flash也會自動給正確的提示(程式碼中不必再宣告, 當然也可以宣告啦)。

    以剛剛拉到舞台上的 ball_mc 為例, 由於 ball_mc 物件為一個影片片段, 如果在定義實體名稱的時候有加上 _mc 為後置結尾名稱, 則在撰寫ActionScript程式碼時使用. 點運算子就會自動跳出所有影片類型中可以使用的屬性及方法(函數), 使用者只需從列表中挑選你所需要的屬性或是方法(雙擊; 阿就是在你要得那項連點兩下啦)即可, 這樣不但方便而且不會打錯字(尤其是可避免自己打有時大小寫字母打錯),如下圖所示。 (如果你關閉了程式碼自動提示的功能,也可點按上方程式碼提示符號強迫給提示!)


    以下是各種類型的元件,Adobe公司建議在命名時所用的後置結尾(suffix)名稱:
    (常用的放左邊前面)

    類別 結尾名稱 類別 結尾名稱
    Button _btn TextFormat _fmt
    MovieClip _mc XML _xml
    TextField _txt XMLSocket _xmlsocket
    String _str Camera _cam
    Sound _sound ContextMenu _cm
    Color _color ContextMenuItem _cmi
    Date _date Error _err
    LoadVars _lv Microphone _mic
    LocalConnection _lc PrintJob _pj
    NetConnection _nc SharedObject _so
    NetStream _ns Video _video
    XMLNode _xmlnode    
    • 註: LoadVars 類別可以用來與網路上的伺服器(Server)互相傳送與接收資料。
    •       LocalConnection 類別可以讓同一部電腦上不同的 Flash 之間互相溝通。
    • @CopyLeft + @CopyWrong + GPL 歡迎轉載 :-)     by tsaiwn@ydu.edu.tw
    再次提醒: 請養成使用正確命名慣例的習慣: 類別(class)名稱第一個字母請用大寫! 物件(object)與變數名稱以及函數名稱第一個字母請用小寫! 還有, Flash 的套件名稱(package name)也有遵守 Java 慣例, 也是全部用小寫。 其實 package name 是反應該套件在磁碟內的目錄結構, package name 其實就是路徑名稱, 也就是說, 相關的類別放在同一個目錄中, 稱之為套件。
    
     Top