android开发笔记之开发规范

前言

来到一个新公司,动手写代码前,我一般都是找领导要开发规范。但是,许多公司都是没有任何开发规范,或者开发规范真是非常简单,只有对修改注释的格式说明,这……。现在的这家公司,我来这二年了,都没有看到什么开发规范,在我的强烈要求下,公司领导才给了一个功能手机开发时代的c++的开发规范,我说要android的java开发规范,领导非常不乐意,就在网上找了一个开发规范文档发给我,还说大家都不是刚开发,应该都知道代码怎么写,……。其实我本意是要公司成立自己的开发规范,说实在话,这个开发规范不是仅仅应付我的要求,应该是公司自己研发质量和体系的自我要求,我其实基本上是不需要什么开发规范文档,因为我写的代码还是比较规范的,但是公司领导的水平实在不怎么样,觉得我就是个trouble maker。好吧,我错了……。以致于后来有人问我,我们写代码有什么讲究没,我想了一下,回了一句,你想怎么写就怎么写,没有人会看你的代码,根本就没有人答理你。这,真是有点绝,但是这就是事实……。

好吧,别人不搞,我们自己来整理一个android开发规范吧,这个以后也是用的着的。

目的

此文档主要是:

  • 统一代码的风格,提高代码的可读性,方便代码维护和移植。
  • 统一代码的约定,方便研发工程师协作,提高工作效率
  • 提高软件质量,减少代码的错误,加强代码的追踪和管理

android开发规范

我们以android开发写代码的顺序来组织此开发规范:

代码修改注释:

我们对代码的任何一条修改都需要使用修改注释,方便代码的修改追踪和管理:

  • java文件:

代码修改注释的开始:

//add—XXX(修改者名字)—XXXX(功能描述)—XXXX(修改日期20150101) —start

代码修改注释的结束:

//add—XXX(修改者名字)—XXXX(功能描述)—XXXX(修改日期20150101) —end
  • xml文件:

代码修改注释的开始:

<!--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文件注释:

<!--*
 * Copyright (C) 2016 XXX(公司名) Inc. 
 * All Rights Reserved.
 * File name:
 * Function:
 * Version:
 * Date:
 *
 *-->

命名规范

命名规范基本上是符合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, if-else, if else-if else 语句

if (condition) {
    statements;
}

if (condition) {
    statements01;
} else {
    statements02;
}

if (condition) {
    statements01;
} else if (condition) {
    statements02;
} else{
    statements03;
}

if语句要注意:

  • 先处理正常的代码路径,再处理不正常的情况
  • 把最常见的情况放在最前面
  • 把正常的情况放在if后面,把不要放到else后面
  • 让if后面跟随一个有意义的语句
  • 利用布尔方法调用简化复杂的条件检测

switch语句

switch (condition) {
    case case1:
        statements01;
        break;
    case case2:
        statements02;
        break;
    case case3:
        statements3;
        break;
    default:
        statements;
        break;
}

switch语句注意:

  • 把正常的情况放在前面
  • 按执行频率排列case子句
  • 每个case后都添加break

循环

for 语句:

for (initialization; condition; update) {
    statements;
}

while语句:

while (condition) {
    statements;
}

do-while 语句:

do {
    statements;
} while (condition);

循环要注意:

  • 保持循环的逻辑简单易读
  • 将循环内的判断外提
  • 尽可能减少在循环内部做的工作
  • 把最忙的循环放在最内层
  • 可以使用一个哨兵值来控制是否退出循环

try-catch 语句

try {
    statements;
} catch (ExceptionClass e) {
    statements;
}

try {
    statements;
} catch (ExceptionClass e) {
    statements;
} finally {
    statements;
}

try-catch 语句注意:

  • catch时,一定要把异常打印出来,绝不允许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 ;
    }

这样一方面可以提高代码的可读性,另一方面,也可以把变更的地方局部化,从而提高可维护性。

Layout 命名

布局文件的命名,我们采用全部单词小写,单词间以下划线分割,尽可能的使用名词或名词组,即使用模块名_功能名称来命名。比如:

contact_tile_list_frequent.xml
contact_editor_activity.xml
group_browse_list_item.xml

资源 ID 命名

layout中所使用的id命名必须以全部单词小写,单词间以下划线分割,尽可能的使用名词或名词组,能够通过id直接理解当前组件要实现的功能。
Button android:id=”@+id/cancel_button”
ImageButton android:id=”@+id/open_details_button”
TextView android:id=”@+id/suggestion_for_contacts_number”

strings.xml 中 ID 命名

命名必须以全部单词小写,单词间以下划线分割,并且尽可能的使用名词或名词组,例如:

<string name="menu_create_contact_shortcut">Place on Home screen</string>
<string name="photo_picker_title">Choose photo</string>

图片资源命名

drawable目录下的图片命名必须以全部单词小写,单词间以下划线分割,尽可能的使用名词或名词组,即使用模块名_用途来命名。如果为公共资源,如分割线等,则直接用用途来命名。比如:

group_icon_1.png
btn_star_on_normal_holo_light.png

控件的使用

以Button为例:
在布局文件定义一个控件:

<Button
    android:id="@+id/cancel_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/quickcontact_suggestion_cancel_button"/>

在java文件使用:

private Button mCancelButton;

mCancelButton= (Button) findViewById(R.id.cancel_button);

mCancelButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        ......
    }
});

log信息

日志信息是对系统的性能有影响的,建议服务器上的代码,把我们开发时的调试日志信息全部删除。

公共方法和接口

有一些是公共方法或接口,建议放在单独新建的文件里,比如(Util.java,Help.java),或是放在系统本身的公共文件中,定义成public static 的形式,方便方法复用。

参考资料:

1.Android开发规范
http://blog.csdn.net/huangyabin001/article/details/30095775
2.代码大全2

猜你喜欢

转载自blog.csdn.net/hfreeman2008/article/details/53261871