Android編程規範

命名規範

1. 基本原則

(1) 代碼風格與android源碼保持一致
(2) 命名要清晰明瞭、有明確含義
(3) 同一產品命名風格要保持一致,避免一意多詞
(4) 同一作用域,不能有變量重名,如局部變量與全局變量重名

2. 包名

(1) package命名如com.brian.xx.yy.zz,xx爲產品,yy爲模塊,zz爲子模塊
(2) 模塊劃分,按以下兩種方式均可,但需要項目組統一
- 按產品業務劃分,如
com.brian.example.homepagecom.brian.example.player
- 按邏輯功能劃分,如
com.brian.example.homepage.uicom.brian.example.homepage.logic

3. 類成員命名,參考android源碼,如android.content.pm.PackageManager

(1) 類:public abstract class PackageManager
(2) 函數:public abstract PackageInfogetPackageInfo(String packageName)
(3) 常量:public static final int GET_ACTIVITIES= 0x00000001;
(4) 靜態變量:static ComponentName sComponent;
(5) 成員變量:ComponentName mComponent;
(6) 臨時變量:ComponentName component;

4. 對於簡單的內部類,或則DTO(數據傳輸對象),成員變量名稱可以不帶前綴m

public final class Message implements Parcelable {
    /**
     * User-defined message code so that the recipient can identify 
     * what this message is about. Each {@link Handler} has its own name-space
     * for message codes, so you do not need to worry about yours conflicting
     * with other handlers.
     */
    public int what;

    /**
     * arg1 and arg2 are lower-cost alternatives to using
     * {@link #setData(Bundle) setData()} if you only need to store a
     * few integer values.
     */
    public int arg1;

    /**
     * arg1 and arg2 are lower-cost alternatives to using
     * {@link #setData(Bundle) setData()} if you only need to store a
     * few integer values.
     */
    public int arg2;
}

5. 接口命名,參考android源碼,如android.view.View.OnClickListener

    /**
     * Interface definition for a callback to be invoked when a view is clicked.
     */
    public interface OnClickListener {
        /**
         * Called when a view has been clicked.
         *
         * @param v The view that was clicked.
         */
        void onClick(View v);
    }

6. 資源命名

(1) 文件名(字母小寫和下劃線組成)
- activity_main.xml
- ic_launcher.png

(2) 資源名id(字母小寫和下劃線組成)
- android:id="@+layout/loading_view"
- <string name="app_name">應用名稱</string>

代碼排版

1. 文字編碼

(1) 統一使用utf8編碼

2. 縮進對齊

(1) 代碼縮進採用4個空格
(2) 代碼行首,合理縮進,以簡潔明瞭爲原則

3. 空格

(1) 條件語句,關鍵字與“(”用空格隔開,如 if (xx)、while (i > 3)
(2) 註釋內容,左右用空格隔開,如 // xxx,/* xxx */
(3) 比較操作符、賦值操作符、算術操作符、邏輯操作符、位操作符,等雙目操作符的前後加空格

    if ( (a >= b) && (c <= d) )
    if (size >= MAX_SIZE)
    a = b + c;
    a *= 2;
    a = b ^ 2;

(4) “!”、”~”、”++”、”–”、”&”(地址運算符)等單目操作符前後不加空格

*p = 'a';
flag = !isEmpty;
p = &mem;
i++;

(5) 逗號、分號(非行結束符號)在後面加空格,前面不加空格

int x = 1, y = 2, z = 3;
function(x, y, z);
for (inti = 0; i < 10; i++)

4. 條件語句(if、for、while、do)

(1) 條件語句,使用完備的括號

if (a == b && c == d) // BAD
if ((a == b) && (c == d))// GOOD

(2) 條件語句,獨自佔一行,執行語句不得緊跟其他

    // BAD
if (flag) doSomething();

    // GOOD
    if (flag) {
        doSomething();
    }

(3) 條件語句,不論語執行句有多少行都要加“{}”

    // BAD
    for (inti = 0; i < 10; i++)
        doSomething();

    // GOOD
    for (inti = 0; i < 10; i++) {
        doSomething();
    }

5. 代碼結構

(1) 一行只寫一條語句

    // BAD
    x = a + b; y = c + d; z = e + f;

    // GOOD
    x = a + b;
    y = c + d;
    z = e + f;

(2) 代碼以“段”來編寫,作用相近的代碼寫在一段,段與段間以空行分開,註釋也相應以“段”來註釋,如

    public void filterData(Data in, Data out) {

        // 預處理
        clip(in.a + 100);
        clip(in.b + 200);
        clip(in.c + 300);

        // 濾波
        intavg  = (in.a + in.b + in.c) / 3;
        int tmp1 = in.a + avg;
        int tmp2 = in.b - avg;
        int tmp3 = in.c + tmp1 + tmp2;

        // 保存結果
        out.a = tmp1;
        out.b = tmp2;
        out.c = tmp3;
    }

(3) 代碼文件中從上到下,函數依次按照調度、被調度的順序出現,例如

    public void funA() {
        funB();
        ...
    }

    public void funB() {
        ...
    }

代碼註釋

1. 基本原則

(1) 註釋語言必須準確、簡潔、易懂,能直接反映編程思路
(2) 統一使用中文作爲註釋語言,除非直接拷貝第三方的英語註釋
(3) 註釋比例沒有嚴格的要求,建議不低於15%
(4) 註釋要與代碼保持一致,代碼作用變了,註釋也要更新
(5) 對於邏輯複雜、使用有限制的代碼,需要重點註釋

2. 必須註釋

(1) 文件
(2) 類
(3) 函數(對外接口public函數)
(4) 常量
(5) 成員變量(有特殊含義)
(6) 靜態變量
(7) 特殊邏輯、定製邏輯、有坑邏輯、臨時邏輯

3. 建議註釋

(1) 複雜的邏輯
(2) 重要的分支,如 if-else,switch-case
(3) 重要的循環,說明,“每次循環遍歷…”

4. 註釋樣式

(1) 註釋樣式參考android源碼
(2) 代碼以“段”來編寫,註釋也相應以“段”來註釋

    /**
    * 函數註釋
    */
    public void foo() {
    }

    /**
     * 函數註釋
     * @param a
     * @param b
     * @return
     */
    public int math(int a, int b) {
    }

    /**
    * 成員變量註釋
    */
    public int mValue;

    // 一段代碼註釋
    xxx
    xxx
    xxx

    xxx
    xxx // 一行代碼註釋
    xxx

    // if分支註釋(1)
    if (true) {
    }
    // else分支註釋(1)
    else {
    }

    if (true) { // if分支註釋(2)
    }
    else { // else分支註釋(2)
    }

    // switch註釋
    switch (xxx) {
        // case註釋(1)
        case xxx : break;
        case xxx : // case註釋(2)
            break;
        default: break;
    }

模塊設計

1. 基本原則

(1) 開放封閉
(2) 單一職責
(3) 倒置依賴
(4) 高內聚低耦合

2. 分層設計

原則上,程序實現業務功能時,按MVC模式,從上至下進行分層設計
(1) 應用層:負責UI展示、下發操作指令
(2) 服務層:負責控制邏輯、數據維護
(3) 數據層:負責底層數據獲取,包括網絡、數據庫、文件、底層算法

3. 模塊交互

(1) 原則上,下層功能代碼不能import上層業務的package,如下層操作數據庫的類不能import上層UI的activity
(2) 上層模塊調度下層模塊,通過下層public接口函數
(3) 下層模塊回調上層模塊,通過interface執行回調(不用handler)
(4) 廣播或則單播監聽事件,同時具有attach和detach操作
(5) 非特殊情況,調度與回調默認在UI線程執行
(6) 非特殊情況,獲取對象的變量統一使用getter、setter操作

4. 代碼分離

(1) 分開:界面代碼、數據代碼
(2) 分開:業務相關代碼、底層通用模塊代碼
(3) 分開:基本模塊、特殊定製模塊

函數設計

1. 基本原則

(1) 一個函數只做一件事
(2) 按抽象層劃分函數
(3) 向下調度原則
(4) 高扇入低扇出

2. 其他建議

(1) 代碼以“段”編寫,合理分隔不相關的代碼段
(2) 禁止代碼中實現與函數名不相關的邏輯
(3) 禁止代碼中出現魔鬼數字
(4) 避免多處出現雷同的代碼,應提取公共的功能函數,或則調整調度入口
(5) 避免嵌套邏輯太深,超過3~5層,建議優化
(6) 避免複雜的複合判斷條件,建議分拆
(7) 避免山寨臨時邏輯
(8) 函數的參數超過5個,則使用參數對象封裝參數,有助於擴展接口
(9) 降低臨時變量的生命週期
(10)廢棄的代碼及時清理

其他參考

  1. 《Android Code Style》
    https://source.android.com/source/code-style.html

  2. 《Java Programming Style Guidelines》
    http://geosoft.no/development/javastyle.html

  3. 《Google Java Style》
    https://google.github.io/styleguide/javaguide.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章