首先要知道爲何要有代碼規範呢?線代軟件產業通過幾十年的發展,一個軟件由一我的完成已經不多見了,軟件都是在相互合做中完成的。那麼合做就意味着你須要「看同伴代碼」,並發表意見見解。
試想若是你的隊友接手到這樣的代碼,有何感想?java
#include<stdio.h> int v, i, j, k, l, s, a[99]; int main() { for(scanf("%d",&s); *a-s; v=a[j*=v]-a[i], k=i<s, j+= (v=j<s&&(!k&&!!printf(2+"\n\n%c"-(!l<<!j)," #Q"[l^v?( l^j)&1:2])&&++l||a[j]<s&&v&&v-i+j&&v+i-j&&v+i-j))&&!( l%=s),v||(i==j?a[i+=k]=0:++a[i])>=s*k&&++a[--i]) ; }
這是每一年一次的國際模糊C代碼大賽於1991年的「最佳小程序」,這個程序的功能是打印出八皇后問題的所有解決方案。我想一個正常人都會以爲這樣的代碼是不可讀的。然而當你的同伴寫出相似如此的代碼,那麼你只能帶把40米的大砍刀了吧!
雖然計算機只關心編譯生成的代碼你的程序採用什麼縮進風格,變量名有無統一等等與執行無關。可是在一個團隊裏面,代碼規範卻十分重要,甚至影響項目的成敗。android
代碼規範分爲兩個部分:
1.代碼風格規範
2.代碼設計規範web
代碼風格規範原則:簡明易讀,無二義性
源文件結構數據庫
一個源文件包含(按順序地):
一、package語句
二、import語句
三、一個頂級類(只有一個)小程序
一、package語句不換行(即package語句寫在一行裏)設計模式
二、 import不要使用通配符
即,不要出現相似這樣的import語句:import java.util.*;併發
不要換行
import語句不換行,列限制(4.4節)並不適用於import語句。(每一個import語句獨立成行)編輯器
順序和間距
import語句可分爲如下幾組,按照這個順序,每組由一個空行分隔:ide
全部的靜態導入獨立成組
com.google imports(僅當這個源文件是在com.google包下)
第三方的包。每一個頂級包爲一組,字典序。例如:android, com, junit, org, sun
java imports
javax imports函數
三、 只有一個頂級類聲明
每一個頂級類都在一個與它同名的源文件中(固然,還包含.java後綴)。
例外:package-info.java,該文件中可沒有package-info類。
縮進:咱們不採用Tab鍵,而是手動輸入4個空格。
雖然Tab鍵通常爲4個空格鍵,但在不少的編輯器中均可以拓展Tab鍵爲多個空格鍵。不採用Tab鍵理由是不一樣狀況可能顯示不一樣的長度,嚴重影響閱讀體驗。
行寬:限定爲100個字符
之前一些規定的行寬爲80個字符過小了,但也不宜過長,影響閱讀質量,所以肯定爲100字符
括號:在複雜的表達式中,用括號清楚地表示邏輯優先級
使讀者可以快速、清楚看出表達式的運算順序
斷行與空白行{}
if(condition) IsFool(); else IsNotFool();
有人喜歡以上的風格,由於這樣能夠省去幾行,彷佛顯得代碼很精簡,看似很高效。可是很是不利於程序的調試,難以有效觀察程序變量的值。所以須要斷行。因而獲得如下代碼:
if(condition){ IsFool(); } else { IsNotFool(); }
這個改進確實不錯,也很清晰美觀。可是還不夠,這樣的程序在多層嵌套時就顯得很無力,難以找到結構的對應關係。因而獲得如下的程序:
if(condition) { IsFool(); } else { IsNotFool(); }
這樣的排版不只美觀,並且清晰,很容易找到結構的對應關係。因此咱們肯定爲這樣的模式:每一個「{」「}」各佔一行。
分行:多條語句不要放在同一行,以下:
a=b;b=c; if(a == b) printf("%d\n",c);
命名:首要原則--見名知意。普通變量採用Camel法,並採用名詞或者組合名詞來命名。而類型、類、函數名採用Pascal法,並採用動詞或者動賓的方式命名。宏則所有采用大寫字母,採用名詞或者組合名詞來命名,多個詞之間用下劃線鏈接。例子以下:
變量(variables)採用Camel命名法。類中控件名稱必須與xml佈局id保持一致。用統一的量詞經過在結尾處放置一個量詞,就可建立更加統一的變量,它們更容易理解,也更容易搜索。例如,請使用strCustomerFirst和strCustomerLast,而不要使用strFirstCustomer和strLastCustomer。
量詞列表 | 量詞後綴說明 |
---|---|
First | 一組變量中的第一個 |
Last | 一組變量中的最後一個 |
Next | 一組變量中的下一個變量 |
Prev | 一組變量中的上一個 |
Cur | 一組變量中的當前變量 |
包(packages): 採用反域名命名規則,所有使用小寫字母。一級包名爲com,二級包名爲xx(能夠是公司或則我的的隨便),三級包名根據應用進行命名,四級包名爲模塊名或層級名
包名 | 此包中包含 |
---|---|
com.xx.應用名稱縮寫.activities | 頁面用到的Activity(activities層級名用戶界面層) |
com.xx.應用名稱縮寫.base | 頁面中每一個Activity類共享的能夠寫成一個i額BaseActivity類 (基礎共享的類) |
com.xx.應用名稱縮寫.adapter } | 頁面用到的Adapter類 (適配器的類) |
com.xx.應用名稱縮寫.tools | 此包中包含:公共工具方法類(tools模塊名) |
com.xx.應用名稱縮寫.bean(或則 com.xx.應用名稱縮寫.unity ) | 此包中包含:元素類 |
com.xx.應用名稱縮寫.db | 數據庫操做類 |
com.xx.應用名稱縮寫.view(或則 com.xx.應用名稱縮寫.ui ) | 自定義的View類等 |
com.xx.應用名稱縮寫.service | Service服務 |
com.xx.應用名稱縮寫.broadcast | Broadcast服務 |
類(classes):名詞,採用Pascal命名法,儘可能避免縮寫,除非該縮寫是衆所周知的, 好比HTML,URL,若是類名稱中包含單詞縮寫,則單詞縮寫的每一個字母均應大寫。
類 | 描述 | 例如 |
---|---|---|
activity 類 | Aty或者Activity爲後綴標識 | 歡迎頁面類WelcomeAty.或者WelcomeActivity |
Adapter類 | Adp或者Adapte 爲後綴標識 | 新聞詳情適配器NewtDetailAdp或則直接 NewDetailAdapter |
解析類 | Hlr爲後綴標識 | 首頁解析類HomePosterHlr |
公共方法類 | Tools或Manager爲後綴標識 | 線程池管理:ThreadPoolManager 日誌工具類:LogTools |
數據庫類 | 以DBHelper後綴標識 | 新聞數據庫:NewDBHelper |
Service類 | 以Service爲後綴標識 | 時間服務TimeService |
BroadcastReceive類 | 以Broadcast爲後綴標識 | 時間通知TimeBroadcast |
ContentProvider | 以Provider爲後綴標識 | |
直接寫的共享基礎類 | 以Base開頭 | BaseActivity,BaseFragment |
layout中的id命名 命名模式爲:view縮寫_模塊名稱_view的邏輯名稱
控件 | 縮寫 |
---|---|
LayoutView | lv |
RelativeView | rv |
TextView | tv |
Button | btn |
ImageButton | imgBtn |
ImageView | mgView 或則 iv |
CheckBox | chk |
RadioButton | rdoBtn |
analogClock | anaClk |
DigtalClock | dgtClk |
DatePicker | dtPk |
EditText | edtTxt |
TimePicker | tmPk |
toggleButton | tglBtn |
ProgressBar | proBar |
SeekBar | skBar |
AutoCompleteTextView | autoTxt |
ZoomControls | zmCtl |
VideoView | vdoVi |
WdbView | webVi |
RantingBar | ratBar |
Tab | tab |
Spinner | spn |
Chronometer | cmt |
ScollView | sclVi |
TextSwitch | txtSwt |
ImageSwitch | imgSwt |
listView | lVi 或則lv |
ExpandableList | epdLt |
MapView | mapVi |
註釋:說明程序作什麼,爲何這麼作。可是不說明怎麼作,由於程序自己就能夠說明。儘可能採用ASCII碼字符,不採用中文或者其餘字符,不然會極大影響程序的可移植性。
一、短註釋採用 //
二、較長註釋用 /* */
錯誤示例: int sum = 0; //i從0開始到9,循環10次,sum依次與i相加 for(int i = 0;i < 10;i++) sum += i; 不該該採用中文,而且註釋沒有必要說明如何作,程序能夠說明 正確示例: int sum = 0; //calculate the sum from 0 to 9 for(int i = 0;i < 10;i++) sum += i;
複雜的註釋應當放在函數頭,不少函數頭的註釋用來講明參數的類型等。
程序註釋必須正確,不然必沒有註釋更糟
註釋不宜過長
代碼設計規範不只是程序書寫的格式問題,並且牽扯到程序設計、模塊之間的關係,設計模式等等。由於咱們設計出的程序可能將被許多人使用,而且須要不斷調試程序,所以遵循如下規範是正確的選擇。
函數:程序的功能絕大部分都由函數來完成。關於函數,最重要的原則就是「只作一件事,而且作好」。
錯誤處理:可能你們以爲主要功能設計完成以後,只須要花不多的一部分時間來給代碼加上一些錯誤處理。而事實上則是相反的,錯誤處理每每要花上整個項目80%的時間。
參數處理:在debug版本,全部參數都要驗證其正確性。正式版本,從外部傳遞來的參數要驗證其正確性
斷言:當你很確切某事會發生時,那麼就能夠斷言!以下:
…… assert(p == NULL) ……
當你不肯定某事是否發生時就須要修改相應的代碼,以下:
…… p = AllocateNewSpace(); //could fail if(p == NULL) ……