首先要知道为何要有代码规范呢?线代软件产业通过几十年的发展,一个软件由一我的完成已经不多见了,软件都是在相互合做中完成的。那么合做就意味着你须要“看同伴代码”,并发表意见见解。
试想若是你的队友接手到这样的代码,有何感想?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) ……