来到一个新公司,动手写代码前,我一般都是找领导要开发规范。但是,许多公司都是没有任何开发规范,或者开发规范真是非常简单,只有对修改注释的格式说明,这……。现在的这家公司,我来这二年了,都没有看到什么开发规范,在我的强烈要求下,公司领导才给了一个功能手机开发时代的c++的开发规范,我说要android的java开发规范,领导非常不乐意,就在网上找了一个开发规范文档发给我,还说大家都不是刚开发,应该都知道代码怎么写,……。其实我本意是要公司成立自己的开发规范,说实在话,这个开发规范不是仅仅应付我的要求,应该是公司自己研发质量和体系的自我要求,我其实基本上是不需要什么开发规范文档,因为我写的代码还是比较规范的,但是公司领导的水平实在不怎么样,觉得我就是个trouble maker。好吧,我错了……。以致于后来有人问我,我们写代码有什么讲究没,我想了一下,回了一句,你想怎么写就怎么写,没有人会看你的代码,根本就没有人答理你。这,真是有点绝,但是这就是事实……。
好吧,别人不搞,我们自己来整理一个android开发规范吧,这个以后也是用的着的。
此文档主要是:
我们以android开发写代码的顺序来组织此开发规范:
我们对代码的任何一条修改都需要使用修改注释,方便代码的修改追踪和管理:
代码修改注释的开始:
//add—XXX(修改者名字)—XXXX(功能描述)—XXXX(修改日期20150101) —start
代码修改注释的结束:
//add—XXX(修改者名字)—XXXX(功能描述)—XXXX(修改日期20150101) —end
代码修改注释的开始:
代码修改注释的结束:
在java或xml文件开关,我们一般要给此文件一个文件的注释,主要是包括版权的声明,文件名、版本信息、日期和作者等等。
java文件注释:
/*
* Copyright (C) 2016 XXX(公司名) Inc.
* All Rights Reserved.
* File name:
* Function:
* Version:
* Date:
*
*/
xml文件注释:
命名规范基本上是符合java和android现有的源码风格,方便代码阅读和代码理解。
名称类型 | 基本规范 | 范例 |
---|---|---|
包(Packages) | 一个唯一包名的前缀总是全部小写的ASCII字母并且是一个顶级域名,通常是com,第二个参数是公司名,第三个参数是功能模块,比如:[域名反转].[项目名].[模块名].[子模块名]…,例如package com.android.contacts; | com.xxx.helloworld(xxx为公司名缩写) |
类(Classes) | 类名采用大小写混合的方式,每个单词的首字母大写。类名应具体,可读,完整表达类的含义。使用完整单词,避免缩写词(除非该缩写词被更广泛使用,像URL,HTML)。继承自系统组件类的命名,后缀必须明确表示出系统组件的类别,Activity类后缀使用Activity,Service类后缀使用Service,BroadcaseReceiver类后缀使用Receiver,ContentProvider使用Provider | Class UsbManager,Class ActivityManager,Class SpeechRecorderActivity, Class AccountService |
接口(Interfaces) | 与类名类似,只是在前加I以表示接口 | interface IActivityManager |
方法(Methods) | 方法名是一个动词+宾语,采用大小写混合的方式,第一个单词的首字母小写,其后单词的首字母大写,以它做什么来命名,而不是以它怎样做命名 | finishActivity(),getID() |
变量(Variables) | 变量名,包括类,类常量,均采用大小写混合的方式,第一个单词的首字母小写,其后单词的首字母大写.变量名应简短,完整,清楚的表达变量的含义.变量名的选用应该易于记忆,即,能够指出其用途。尽量避免单个字符的变量名,除非是一次性的临时变量。 临时变量通常被取名为 i,j,k,m 和 n,它们一般用于整型;c,d,e,它们一般用于字符型.非 public 的、非 static 的字段名称以 m 开头。static 字段名称以 s 开头。其它字段以小写字母开头 | int i,j,k; Context mContext;PackageManager mPm;Button mOk;Uri mOriginatingURI;private static MyClass sSingleton |
常量(Constants) | 类常量的声明全部大写,单词间用下划线隔开 | public static final int START_VOICE_HIDDEN_SESSION = -10; |
在java文件,文件注释之后就是包和引入,
package主要是包的路径,这要符合开发的定义,比如android的一个包:
package com.android.contacts;
package com.android.server.usb;
我们可以自定义package:
package com.XXX.helloword
XXX为公司的英文名。
同一包中的类在导入时应声明在一起,无效的未使用到的引用要删除:
import样例:
import android.content.Context;
标准的注释:
/**
* 类或接口的说明
* @see 相关的类或接口
*/
但是,如果类比较简单,我们也可以直接用一句话描述此类或接口的功能
比如UsbAlsaManager类的注释:
/**
* UsbAlsaManager manages USB audio and MIDI devices.
*/
方法的规范要求比较多:
(1)方法的名称要清晰描述方法的功能,建议是动词+宾语(例如getID)
(2)方法的职责单一,功能明确(是符合单一职责原则)
(3)方法的长度合适,不要太长,也不要太短,最好是体现接口隔离原则,接口尽量颗粒化
(4)方法的参数数量和顺序要合适,参数数量不要太多,参数的顺序要有一定的顺序,比如按照in–modify–out的顺序排列
(5)方法的注释要合理,方便阅读
(6)方法的布局和风格要一致
(7)方法尽量不要使用神秘数
(8)方法要符合迪米特法则,尽量不要使用不是参数的其它变量,降低方法的耦合性,提高方法的内聚性,也方便移植
(9)方法要有相应的处理异常,错误的手段,提高方法的健壮性。
比如:
/**
* 一句话描述方法
* 方法详细描述
* @param 参数,说明
* @param 参数,说明
* @return 返回值,说明
* @throws 异常,说明
* @see 相关的方法
*/
public boolean functionName(int param_0,boolean param_1) {
boolean result = false;
...........;
return result;
}
当然,许多时候,方法简单明了,根本就不需要方法的注释,我们可以不添加注释,也可以只添加一个对方法简单描述的注释。比如:
/**
* Show the overflow items from the associated menu.
* @return true if the menu was able to be shown, false otherwise
*/
public boolean showOverflowMenu() {
return mMenuView != null && mMenuView.showOverflowMenu();
}
成员变量注释:
/**
* 成员变量描述
*/
private String test;
/** 成员变量描述 */
private int hello;
// Buttons to indicate user acceptance
private Button mOk;
常量注释:
// Dialog identifiers used in showDialog
private static final int DLG_BASE = 0;
大括号不单独占用一行,应紧接着上一行。比如:
public class NullObject extends AbstractObject {
........
public void doAction() {
......
}
}
if (condition) {
statements;
}
if (condition) {
statements01;
} else {
statements02;
}
if (condition) {
statements01;
} else if (condition) {
statements02;
} else{
statements03;
}
if语句要注意:
switch (condition) {
case case1:
statements01;
break;
case case2:
statements02;
break;
case case3:
statements3;
break;
default:
statements;
break;
}
switch语句注意:
for 语句:
for (initialization; condition; update) {
statements;
}
while语句:
while (condition) {
statements;
}
do-while 语句:
do {
statements;
} while (condition);
循环要注意:
try {
statements;
} catch (ExceptionClass e) {
statements;
}
try {
statements;
} catch (ExceptionClass e) {
statements;
} finally {
statements;
}
try-catch 语句注意:
try {
statements;
} catch (ExceptionClass e) {
//什么都不做
}
try {
statements;
} catch (ExceptionClass e) {
//什么都不做
} finally {
statements;
}
所谓魔法数值,是指在代码中直接出现的数值。
比如:
public void magicFunction() {
int i = 1000;
}
我们不知道这个100从那里来,表示什么意义。正确的使用方式为:
public static final int NUMBER_LIGHT = 1000;
public void magicFunction() {
int i = NUMBER_LIGHT ;
}
这样一方面可以提高代码的可读性,另一方面,也可以把变更的地方局部化,从而提高可维护性。
布局文件的命名,我们采用全部单词小写,单词间以下划线分割,尽可能的使用名词或名词组,即使用模块名_功能名称来命名。比如:
contact_tile_list_frequent.xml
contact_editor_activity.xml
group_browse_list_item.xml
layout中所使用的id命名必须以全部单词小写,单词间以下划线分割,尽可能的使用名词或名词组,能够通过id直接理解当前组件要实现的功能。
Button android:id=”@+id/cancel_button”
ImageButton android:id=”@+id/open_details_button”
TextView android:id=”@+id/suggestion_for_contacts_number”
命名必须以全部单词小写,单词间以下划线分割,并且尽可能的使用名词或名词组,例如:
<string name="menu_create_contact_shortcut">Place on Home screenstring>
<string name="photo_picker_title">Choose photostring>
drawable目录下的图片命名必须以全部单词小写,单词间以下划线分割,尽可能的使用名词或名词组,即使用模块名_用途来命名。如果为公共资源,如分割线等,则直接用用途来命名。比如:
group_icon_1.png
btn_star_on_normal_holo_light.png
以Button为例:
在布局文件定义一个控件:
在java文件使用:
private Button mCancelButton;
mCancelButton= (Button) findViewById(R.id.cancel_button);
mCancelButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
......
}
});
日志信息是对系统的性能有影响的,建议服务器上的代码,把我们开发时的调试日志信息全部删除。
有一些是公共方法或接口,建议放在单独新建的文件里,比如(Util.java,Help.java),或是放在系统本身的公共文件中,定义成public static 的形式,方便方法复用。
1.Android开发规范
http://blog.csdn.net/huangyabin001/article/details/30095775
2.代码大全2