命名基本原则
- 驼峰式
- 描述性:有一定的意义,避免难懂的名称
- 唯一性:同一个类中的字段避免相似同义的字段名
- 使名称足够长以便有一定的意义
分类命名规范
包的命名:com.woyou.项目名 具体参考基础框架的结构和命名
类的命名:
类的名字必须由大写字母开头而单词中的其他字母均为小写;如果类名称由多个单词组成,则每个单词的首字母均应为大写例如TestPage;如 果类名称中包含单词缩写,则这个所写词的每个字母均应大写,如:XMLExample,还有一点命名技巧就是由于类是设计用来代表对象的,所以在 命名类时应尽量选择名词。 例如: Circle常用类命名规范
Activity:描述+Act
Fragment:描述+Frag
View:描述+View
Receiver:描述+Receiver
Service:描述+Service
请求bean:请求描述+Req
字段和函数的命名:
首字母小写的驼峰式命名,方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头。例如:txtTitle、 sendMessage()常量的命名
常量的名字应该都使用大写字母,并且指出该常量完整含义。如果一个常量名称由多个单词组成,则应该用下划线来分割这些单词。例如: MAX_VALUE参数的命名
参数的命名规范和方法的命名规范相同,请尽量保证参数的命名尽可能明确。基本数据类型与常用数据类型命名规范
Integer:int+描述 Char:chr+描述 Boolean:bln+描述
Long:lng+描述 Short:shr +描述 Double:dbl+描述
String:str+描述 Float:flt+描述 Single:sng+描述
DataTime:dt+描述 int[](数组):arr+描述 Object:obj+描述
List:描述+List
局部变量:String srtName;
全局变量 : String mStrName; 如果是全局变量就在变量名加上m字母再将第二个单词首字母改为大写。
- 控件命名规范(编码与XML的id)
TextView 代码:txt+描述 ;XML id:txt_+描述 (下面不再详述) 全局变量:mTxt+描述,局部变量:txt+描述 (全局与局部的区别下面不再详述)
Button :btn+描述 ;
ImageButton :ib+描述
ImageView :img+描述
CheckBox :chk+描述
RadioButton :rb+描述
AnalogClock :ac+描述
DigitalClock :dc+描述
DatePicker :dp+描述
TimePicker :tp+描述
ToggleButton :tb+描述
EditText:edit+描述
ProgressBar:pb+描述
SeekBar:sb+描述
AutoCompleteTextView:autotxt+描述
MultiAutoCompleteTextView:mlautotxt+描述
ZoomControls:zc+描述
Include:ind+描述
VideoView:vv+描述
WebView:wv+描述
RatingBar:ratbr+描述
Tab:tab+描述
Spinner:spin+描述
Chronometer:chro+描述
ScrollView:sv+描述
TextSwitcher:tswi+描述
Gallery:gal+描述
ImageSwitcher:imgswi+描述
GridView:gv+描述
ListView:lv+描述
ExpandableList: exl+描述
MapView: mv+描述
- 其他变量命名规范
变量命名:前缀+类型描述+意义描述
例如:全局变量 mSelectorOnItemTouch或者局部变量 selectorOnItemTouch
注释
- 文件注释(记录每次的修改人、时间和内容)
/*
* @Title: ${file_name}
* @author: tomcat
* @data: ${date} ${time} <创建时间>
*
* @history:<以下是历史记录>
*
* @modifier: <修改人>
* @modify date: ${date} ${time} <修改时间>
* @log: <修改内容>
*
* @modifier: <修改人>
* @modify date: ${date} ${time} <修改时间>
* @log: <修改内容>
*/
- 类注释
/**
* ${todo}<请描述这个类是干什么的>
* @author tomcat
* @versionCode 1 <每次修改提交前+1>
*/
- 函数(方法)注释
/**
* public函数
* ${todo}<请描述这个方法是干什么的>
* @param pos <参数说明>
* @throw
* @return ${return_type} <返回值说明>
*/
public Object getItemByPos(int pos){
.......
}
//<请描述这个方法是干什么的>
private void create(){
// 在函数中也可适当添加注释
}
- 成员变量注释
private Context mContext; //上下文对象
private TextView txtTitle; //标题
private int lastTouchX; //最后手指按下时的X轴坐标
- 局部变量注释
局部变量和逻辑块也要适当加上// 注释
public InputStream open(){
String webUrl = "www.baidu.com"; //要连接的网址
......
......
}
- 每一个类、字段与函数必须有注释,注释行数不少于代码行数的五分之一(提醒作用 不强制)
编码规范
1 明确方法功能,精确实现方法设计,一个函数仅完成一个功能。
2 函数的调用者应该负责对参数的合法性检查,参数的合法性检查尽量不要放在函数中实现(视情况而定)
public Goods getGoodsByName(String name){
if( TextUtils.isEmpty(name) ){
return null;
}
......
......
}
{
Goods goods = getGoodsByName(name);
if( goods == null ){
return;
}
......
......
}
X
{
if( TextUtils.isEmpty(name) ){
return;
}
Goods goods = getGoodsByName(name);
......
......
}
√
3 明确类的功能,精确(而非近似)地实现类的设计。一个类仅实现一组相近的功能。
划分类的时候,应该尽量把逻辑处理、数据和显示分类,实现类功能的单一性
比如:
数据类不能包含数据处理的逻辑,比如Bean实体
通信类不能包含显示处理的逻辑,比如Socket、DownloadManger
4 所有数据类必须重载toString()方法, 返回该类有意义的内容。
public TopoNode{
private String nodeName;
public String toString(){
return "NodeName : " + nodeName;
}
}
5 数据库、IO操作等使用后需要close()的对象必须在try-catch-finally的finally中close().
try
{
// . . . . . .
}
catch(IOException ioe)
{
// . . . . . .
}
finally
{
try
{
out.close( ) ;
}
catch(IOException ioe)
{
// . . . . . .
}
}
6 避免使用不易理解的数字,用有意义的标识来替代。涉及物理状态或者有意义的数字,必须用有意思的静态常量来代替。所有switch case 的int值包括message的what值都必须有常量来描述并加上注释。
可读性差的代码:
switch (code) {
case 1:
... ...
break;
X
private final static int IDLE = 1; //空闲状态
switch (code) {
case IDLE:
... ...
break;
√
7 View的显示控制逻辑最好放在Controller中(使用MVC时)
8 Activity与Fragment中的代码不允许超过400行,最好控制在300行以内,超过400行代码的Activity意味着你的代码可能没有做任何封装和划分,是时候优化你的代码了。
9 所有超过20行的抽象实现类(或者匿名内部类)都必须抽出来单独实现再实例化,禁止运行时实现, 与执行过程无关的代码尽量不要放在执行过程中
重构前:
{
testTimerTask=new TimerTask() {
@Override
public void run() {
runOnUI(new Runnable() {
public void run() {
List netData=NetworkStrengthController.getInstance(mContext).getNetData();
if(!netData.isEmpty()){
strength_now.setText("当前信号强度:"+netData.get(netData.size()-1)+"dB");
strength_max.setText("信号强度最高:"+Collections.max(netData)+"dB");
strength_low.setText("信号强度最低:"+Collections.min(netData)+"dB");
if(netStates.size()>0){
strength_base.setText("连接基站个数:"+netStates.size());
}
//评级
if(netStates.size()>3){
strength_rate_iv.setImageResource(R.raw.netstrength_poor);
}else{
float sum=0;
for(float num: netData){
sum=sum+num;
}
float avg=sum/netData.size();
if(avg>-60){
strength_rate_iv.setImageResource(R.raw.netstrength_good);
}else if(avg>-90){
strength_rate_iv.setImageResource(R.raw.netstrength_normal);
}else if(avg>-110){
strength_rate_iv.setImageResource(R.raw.netstrength_poor2);
}else{
strength_rate_iv.setImageResource(R.raw.netstrength_poor);
}
}
}
}
});
}
};
testTimer.schedule(testTimerTask, 0, 1000);
}
XXX
重构后:
public class NetworkController{
//注释
public setStrengthNow(TextView tv){
int now = getStrengthNow();
tv.setText("当前信号强度:"+ now +"dB");
}
//注释
public setStrengthMax(TextView tv){
int max = getStrengthMax();
tv.setText("信号强度最高:"+ max +"dB");
}
//注释
public setStrengthLow(TextView tv){
int low = getStrengthLow();
tv.setText("信号强度最低:"+ low +"dB");
}
//显示信号强度评级
public void setStrengthRate(ImageView iv){
... ... //计算评级
... ...//设置显示
}
}
Activity代码:
Runnable runTest = new Runnable(){
public void run() {
boolean hasSignal = mNetworkController.hasSignal(); //是否检测到信号
if(hasSignal){
//显示信号强度
mNetworkController.setStrengthNow(txtStrengthNow);
mNetworkController.setStrengthMax(txtStrengthMax);
mNetworkController.setStrengthLow(txtStrengthLow);
.....
//显示评级
mNetworkController.setStrengthRate(ivStrengthRrate);
}
}
}
{
testTimerTask=new TimerTask() {
@Override
public void run() {
runOnUI(runTest);
}
};
testTimer.schedule(testTimerTask, 0, 1000);
}
√√√
11 Activity与Service之间的通信只能使用广播或者Binder代理对象
12 ListView的Adapter的getView函数代码统一使用自定义View来封装(也就是每一种Item都是一类自定义View)
13 所有相似的Dialog弹出框逻辑都抽取到Utils中便于复用。
14 禁止直接new Thread()必须使用线程池启动线程。
15 逻辑复杂的一块UI应封装为自定义View,良好的Activity结构应该由多个自定义View组成,以减少Activity中的代码
16 布局能用一层就用一层尽量减少布局嵌套
17 注释的代码能删除就删除不要留着。
18 UI模块较多的项目,Activity应该按模块分包
19 函数的实现横不可超过半屏幕竖不可超过一屏 超过了就要按逻辑块抽出别的子函数。
20 用不到的第三方库就删掉
21 禁止使用静态变量在activity和activity之间、activity和service之间共享数据
22 Activity中在一个View.OnClickListener中处理所有的逻辑
23 不要重用父类的handler,对应一个类的handler也不应该让其子类用到,否则会导致message.what冲突
24 如果多个Activity中包含共同的UI处理,那么可以提炼一个父Activity,把通用部分封装起来由它来处理,其他activity只要继承它即可
25 屏幕适配:使用适配方案的值写死所有控件的尺寸
26 view与view之间不要直接通信 应该通过activity来转接
27 不要使用Log.i() Log.d() 进行日志打印,应该使用一个包含统一开关的测试类进行统一打印。比如封装一个LogUtils。
28 异常捕获不要直接catch(Exception ex),应该把异常细分处理
29 如果多段代码重复做同一件事情,说明此段代码各语句之间有实质性关联并且是完成同一件事,那么可以把此段代码构造成一个 新的函数。
30 不要使用难懂的技巧性很高的语句,除非很有必要时。