项目开发规范
在项目开发过程中,如果开发人员过多又没有一个开发统一规范,在后期的维护、迭代升级的过程中会相当痛苦,也不利于新人接收项目,项目规范是为了统一一个开发标准,让代码易懂便于维护升级。
在这里将所有日常开发中用到的ID、命名、包层次等定一个标准,以后开发就按此规则来开发代码,有利于代码的可读性、提高开发效率。任何地方定义名称、ID都应遵循望文知意、驼峰表示的原则,所取的名字在保证意思明了的前提下尽量短小。
1. 命名规范
1.1 包名
项目的组织层次结构以项目的逻辑、功能点为单位来组织包的结构,比如用户登录、注册等划分在同一个功能点,则与登录注册相关的界面Aactivity、Fragment、Service等都放在com.hyj.xxx.login的包下面。以下是一些通用的包层次规则说明。
包名 | 说明 |
com.hyj.xxx | 项目根目录 |
com.hyj.xxx.Constatns | 常量类,项目中需要用到的全局常量都统一放在此类中,方便统一管理。 |
com.hyj.xxx.bean | 存放Bean类容 |
com.hyj.xxx.tools | 存放通用工具类 |
com.hyj.xxx.system | 存放于系统相关的类 |
com.hyj.xxx.db | 数据库、数据持久化的操作,如sharedprefeners里面数据的操作,都可以放在这个包中 |
com.hyj.xxx. service | 存放全局Service组件,如果是局部使用的则放入到相应的逻辑包中即可 |
com.hyj.xxx. receiver | 存放全局广播类,如果是局部使用的则放入相应的逻辑包中即可 |
com.hyj.xxx. network | 与网络相关的类 |
com.hyj.xxx.view | 项目自定义组件 |
com.hyj.xxx.view.xxx | 项目中复杂自定义组件,超过一个类才能实现自定义效果的 |
com.hyj.xxx.dao | 存放接口的定义 |
com.hyj.xxx.dao.impl | 存放接口的实现 |
com.hyj.xxx. abstract | 存放全局的抽象类 |
1.2 类名
抽象类规则:以A开头+业务名或简称;如ABaseActivity
Actiivty规则:业务名或简称+Activity结尾;如LockActivity。
Fragment规则:业务名或简称+Fragment结尾;如LockQuestionFragment。
Adapter规则:业务名或简称+Adapter结尾;如PwdAdapter。
Service规则:业务名或简称+Service结尾;如SmsService。
BroadcastReceiver规则:业务名或简称+ Receiver结尾;如SmsReceiver。
ContentProvider规则:业务名或简称+ Provider结尾;如DataProvider。
Application规则:项目名或简称+Application结尾;如CodeApplication。
JavaBean规则:业务名或简称+Model结尾。
Adapter中的ViewHolder规则:业务名或简称+Holder结尾。s
自定义组件命名:
自定义组件:业务名或简称+View;如ClockView。
自定义容器:业务名或简称+Layout;如SquareLayout。
1.3 接口
接口命名需要简单明了,长度不宜过长;
接口定义:
以I开头+业务+业务类型;如数据库操作接口:IItemDao,是一个类型查询接口的定义。
接口实现:
以I开头+接口定义名+Impl;如数据库接口实现:IItemDaoImpl,类型查询接口的实现。
1.4 常量
常量用于常驻内存且无变化的值,定义的时候遵循望文知意的原则;常量中的字母全部大写,如果有多级则用”_”连接;
规则:一级业务_二级业务;如SUCCESS、RESULT_OK。
1.5 变量
变量命名应尽量短小,望文知意,使用驼峰命名的总原则。
以下两种情况具体说明:
1) 若是引用类型变量则建议变量添加前缀“m”;
2) View组件变量,View组件简称+XML文件中定义的ID名称
常用的View组件的简称如下:
组件 | |
TextView | tv |
EditText | et |
AutoCompleteTextView | actv |
MultAutoCompletTextView | mactv |
Button | bt |
CheckBox | cb |
RadioButton | rb |
RadioGroup | rg |
ToggleButton | tb |
ImageButton | ib |
CompoundButton | cb |
ImageView | iv |
ProgressBar | pb |
SeekBar | sb |
WebView | wv |
容器 | |
LinearLayout | ll |
RelativeLayout | rl |
FrameLayout | fl |
GridLayout | gl |
ScrollView | sv |
HorizontalScrollView | hsv |
1.6 方法
方法名字应该简单明了、含义明确,首字母小写,按驼峰命名原则书写。所有初始化的方法格式为initXxx(),每一个init做一件事。
在一个方法中不允许实现太多代码,吐过一个方法有大百行代码、有好几个逻辑的时候,应该按照功能点拆分出多个方法,便于阅读理解。另外出现功能一样的实现逻辑,应该及时抽取出公用的方法,不允许将实现逻辑复制到多个地方用。
在事件响应的时候,不允许在匿名内部类中写实现逻辑,应该将实现逻辑单独拿出来放到方法中,例如:
lvDevice.setOnItemClickListener(newOnItemClickListener() { @Override publicvoid onItemClick(AdapterView<?> parent, View view,int position, long id){ BlueDevicewrist = (BlueDevice) parent.getItemAtPosition(position); braConnect(wrist); } }); private void braConnect(BlueDevice wrist){ mac= wrist.getAddress(); showProgressDialog(); BraceletConnect(wrist); }
1.7 布局
全部名字都是小写字母,开头为类名,中间以“_”连接。因为所有的布局都放在这个文件夹下面,这个文件夹中的文件命名分一下几种情况;
1) 布局文件,类名_一级业务名.xml;
列表项的xml布局文件名称:类名_item.xml;
activity类的xml文件名称:类名_activity.xml;
fragment类的xml文件名称:类名_fragment.xml;如定义LoginActivity的xml文件名称,则可以定义为login.xml;
2) 自定义组件
项目中自定义组件命名规范,view_类名;如view_popup.xml是一个下拉类型选择组件的布局文件。
3) 通用工具类布局文件
项目中通用工具的布局文件命名规范,一级业务_二级业务.xml;如title.xml是通用标题栏,title_pop.xml是特定界面带下拉的标题栏。
1.8 ID命名
在Android中有很多地方都会用到ID属性,当ID命名多了以后往往会造成重复,当使用Ctrl+鼠标左键定位到具体的布局文件中的时候,有时就会定位不准确,因此保证ID的易懂、唯一性也是很有必要的。ID命名应遵循望文知意、驼峰原则,不建议使用“_”连接,因为在java代码编写的时候感觉不方便。
规则:类名+组件简称+业务名或简称;如loginEtName。在Java文件中定义变量名可以定义为etName。
1.9 资源
Android项目中会用到很多的资源,图片、声音、String、Drawable是比较常用的资源,资源文件的命名遵循以资源实际作用来命名的基本原则,如果是局部使用的资源则以类名+业务名或简称的方式来命名。以下列举了几种常见的规则:
1) Drawable中的资源,根据特定的使用场景,使用在什么组件上命名。
组件上使用规范:组件简称_业务类型.xml;如按钮点击效果,btn_blue.xml表示按钮未点击时时蓝色的效果。
通用资源规范:效果类型_使用场景.xml;如一个可以使用在item、textview、edittext中的边框效果命名方式为,border_blue.xml表示蓝色边框效果。
2) 应用中的图标,图标作用.png;比如返回图标back.png。
3) 其他资源命名
其他Strings、colors等文件里面的命名规则,则根据具体使用场景的业务名字命名;比如styles.xml中分割线的命名,line_horizontal表示应用中使用的默认水平线分割样式,line_horizontal_gray表示灰色的水平分割线。
1.10 目录
主要是一些jar包、so文件的配置目录名称,全部是小写字母,望文知意的基本原则。
现在的项目目录结构基本够用,后期增加的机会不过,现列举出系统中存在的目录结构:
lib:第三方jar的保存路径;
jniLibs:jni引用的so文件的目录;
2. 注释规范
2.1 类注释
在类、接口定义之前当对其进行注释,包括类、接口的目的、作用、功能、继承于何种父类,实现的接口、实现的算法、使用方法、示例程序等。
/** * 描述 *@Author hyj * @Date2017-1-19 上午9:35:03 */
2.2 方法注释
方法注释的模板:
/** *描述 * @param参数名参数描述 * @param参数名2 参数描述 *@return 返回值类型说明 *@throws Exception 异常说明 */
2.3 类成员变量和常量注释
成员变量和常量需要使用如下注释的形式,注释位于变量的上侧;
/** *描述 **/
2.4 内部逻辑注释
内部逻辑注释模板:
if (response.getRet() == 0) {//支付成功 Toast.makeText(H5Activity.this, "支付成功", Toast.LENGTH_LONG).show(); goToNext(response); }else if (response.getRet() == -1) {//支付失败 Toast.makeText(H5Activity.this, "支付失败", Toast.LENGTH_LONG).show(); //刷新当前页面 reflush(currentUrl); }
2.5 TODO注释
对那些临时性的、短期的、够棒但不完美的代码,需要Mark一下,后期优化或者需要进一步做处理的代码,使用 TODO 注释、标记。TODO 注释是表示“将来要做某事”的格式。
TODO 注释应该包含全部大写的TODO,后跟一个冒号:
// TODO: Remove this code after the UrlTable2has been checked in. // TODO: Change this to use a flag instead of aconstant.
3. 代码顺序
3.1 方法排序
在一个典型的Activity中代码的顺序如下:
/** * 描述 *@Author hyj * @Date2017-1-19 上午9:35:03 */ public class ClassName { //(1) 成员常量集合 //(2) 成员变量集合 //(3) 回调方法集合 若该类为activity,则:onCreate、**、onDestory; 若该类为Fragment、则:onCreateView、**、onDestory; //(3) 其他方法集合 }
3.2 初始化方法
在类中有许多初始化参数、点击事件等,这里都规定放在指定的方法中,便于查找形成习惯。
public void onCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.webbrowser); myInit(); } /** * 初始化操作 */ @override private void myInit() { super.myInit(); initView(); initData(); initListener(); } /** * 标题初始化 */ @override private void initTitle() { initTitleAndBottom(); title.setText(""); subArea.setVisibility(View.GONE); } /** * view初始化 */ private void initView() { } /** * 初始化数据 */ private void initData() { } /** * 所有监听事件 */ private void initListener() { }
4. 代码规范
代码中代码风格以IDE中格式化后的代码格式为标准,在代码提交的时候都得格式化一遍,便于阅读、理解。因为各个各个IDE环境的格式化标准不一样,一下列举一些比较常见、看上去比较舒服的格式作为示例。
4.1 大括号换行
左大括号不换行,右大括号换行;
public class MyClass { intfunc() { if (something) { // ... }else if (somethingElse) { // ... }else { // ... } } }
4.2 小括号空格
if (condition) { body(); } // 推荐
4.3 缩进
4 个空格作为缩进排版的一个单位,不使用制表符 tab。
8 个空格作为换行后的缩进,包括函数调用和赋值。
Instrument i = someLongexpression_r(that, NotFit, on, one,line); // 推荐
4.4 每一行的长度
尽量避免一行的长度超过 100 个字符。
例外:如果注释行包含了超过 100 个字符的命令示例或者 url 文字,为了便于剪切和复制,其长度可以超过 100 个字符。
例外:import 行可以超过限制,因为很少有人会去阅读它。这也简化了编程工具的写入操作。
4.5 每次声明一个变量
推荐一行一个声明,因为这样以利于写注释;
private int level; // indentation level private int size; // size of table
4.6 if-else语句
在使用此语法的时候应避免重复嵌套,if里面还套有多重if等其他带大括号的语句,这样会导致代码层次结构很复杂,并且在if-else的大括号内代码不应过长,控制在10行以内,代码过长的情况应直接return返回或抽取出一个方法来执行。
if-else语句应该具有如下格式:
if (condition) { statements; } if (condition) { statements; } else { statements; }
如果大括号内代码行数过多,可以根据情况使用以下格式:
if (condition) { statements; return; } statements;
if (condition) { statements; } else if (condition) { statements; } else{ statements; }
注意:if语句总是用”{“和”}“括起来,不能使用如下容易引起错误的格式:
if (condition) // 禁止使用这种格式 statement;
4.7 for语句
一个for语句应该具有如下格式:
for (initialization; condition; update) { statements; }
当在for语句的初始化或更新子句中使用逗号时,避免因使用三个以上变量,而导致复杂度提高。若需要,可以在for循环之前(为初始化子句)或for循环末尾(为更新子句)使用单独的语句。
4.8 while语句
一个while语句应该具有如下格式:
while (condition) { statements; } do-while语句: do { statements; } while (condition);
4.9 switch语句
一个switch语句应该具有如下格式:
switch (condition) { caseABC: statements; /* falls through */ caseDEF: statements; break; caseXYZ: statements; break; default: statements; break; }
每当一个case顺着往下执行时(因为没有break语句),通常应在break语句的位置添加注释。