Android编码规范_优码客软件

 

 

 

 

 

Android编码规范

 

 

 

 

 

 

 

 

 

 

日期

作者

备注

2013年7月30日星期二

王明东

初稿

 

 

 


 

前  言

编写本规范的目的是为了进一步规范Android软件编程风格,提高软件源程序的可读性、可靠性和可重用性,确保在开发成员或开发团队之间的工作可以顺利交接,不必花很大的力气便能理解已编写的代码,以便继续维护和改进以前的工作,提高软件源程序的质量和可维护性,减少软件维护成本。

本规范的内容包括:注释、命名规则、等。

本规范分成规则性和建议性两种:对于规则性规范,要求所有软件开发人员严格执行;对于建议性规范,开发人员可以根据实际情况选择执行。

自本规范实施之日起,以后新编写的和修改的代码均应执行本规范。

本规范用到的术语解释如下:

规则:编程时必须遵守的规则。

建议:编程时必须加以考虑的原则。

说明:对相应规则的必要的解释。

正例:对此规则或建议给出的修正后的例子。

反例:对此规则或建议给出的反面的例子。


 

1    注释

注释有助于理解代码,有效的注释是指在代码的功能、意图层次上进行注释,提供有用、额外的信息,而不是代码表面意义的简单重复。

Java程序有两类注释:实现注释,文档注释。

1.1  实现注释

实现注释是那些在C++中见过的,使用/*…*/和//界定的注释。

【规则1-1-1】注释应与其描述的代码相近,对代码的注释应放在其上方(需与其上面的代码用空行隔开)或右方(对单条语句的注释)相邻位置,不可放在下面。

说明:在使用缩写时或之前,应对缩写进行必要的说明。避免在代码行的末尾添加注释;行尾注释使代码更难阅读。不过在批注变量声明时,行尾注释是合适的;在这种情况下,将所有行尾注释在公共制表位处对齐。代码如果超过行在中间加入关键部分的注释。


 

1.2  文档注释

文档注释(被称为“doc comments”)是Java独有的,并由/**…*/界定,注释内容里包含标签。文档注释可以通过javadoc工具转换成HTML文件。

实现注释用以注释代码或或者实现细节。文档注释从实现自由(implemtentation-free)的角度描述代码的规范。它可以被那些手头没有源码的开发人员读懂。

 

【规则1-2-1】注释使用中文注释。与doc有关的标准英文单词标签保留。

 

标签

用处

用途

@author作者的名称

类、接口

说明特定某一段程序代码的作者。每一个作者各有一个标记。

@deprecated

类、方法

说明该类的应用程序编程接口 (API) 已被废弃,因此应不再使用。

@exception  name description

方法

说明由方法发出的异常。一个异常采用一个标记,并要给出异常的完整类名。

@param  name 参数名的描述

方法

用来说明传递给一个方法的参数,其中包括参数的类型/类和用法。每个参数各有一个标记。

@return方法返回值的描述

方法

若方法有返回值,对该返回值进行说明。应说明返回值的类型/类和可能的用途。

@since

类、方法

例如: sinceJDK 1.1:说明自从有 JDK 1.1 以来,该项已存在了多长时间。

@see 类名

类、接口、方法、字段

在文档中生成指向特定类的超文本链接。可以并且应该采用完全合法的类名。

@seeClassName#memberfunctionName

类、接口、方法、字段

在文档中生成指向特定方法的超文本链接。可以并且应该采用完全合法的类名。

@version版本号

类、接口

说明特定一段代码的版本信息。

 

 

【规则1-2-2】类、接口头部必须进行注释。

说明:注释必须列出:类、名称、内容摘要等。

类编号由功能模块编号和类名两部分组成,中间用“_”隔开,功能模块编号使用该类所在

的功能模块的编号,类名用类的名称。例如:M01_Employee。

正例:

下面是类头部的中文注释:

/**

* 类名称

* 内容摘要//说明主要功能。

* @author UMK.XX

* @since 2013/07/30 修改说明

*/

 

 

【规则1-2-3】公共方法前面应进行文档型注释。

说明:注释必须列出:方法编号、主要功能、参数类型、输入参数、返回值、调用的前置条件和后置条件、异常说明、关键算法、可见性决策等。

正例:

下面是公共方法头部的注释:

       /**

* 方法名称

* 方法摘要//说明主要功能。

* @author UMK.XX

* @since 2013/07/30 修改说明

* @param param1 参数一说明,

* @param param1 数据1

* @param param2 数据2

* @return 返回测试值 、意义(如:数值,1:成功,0:失败)

*/

 

 

〖建议1-2-1〗Java语言中,公共的属性采用单行文档注释,对于需要比较多的声明的,可进行多行注释。

说明:如果是Javadoc注释,属性可以采用文档型注释。

正例:

对于public型变量的单行声明:

/** classVar1 对classVar1的声明 */

public static int classVar1;

 

对于public型变量的多行声明:

/**

 *classVar1 对classVar1的声明第一行

 *对classVar1的声明第二行(继续对classVar1的声明)

 */

public static int classVar1;

 

对于public型变量的多行声明:

/**

 *classVar1 对classVar1的声明第一行

 *对classVar1的声明第二行(继续对classVar1的声明)

 */

public static int classVar1;

 

〖建议1-2-2〗通过对方法、变量等正确的命名以及合理地组织代码结构,使代码成为自注释的。

说明:清晰准确的方法、变量的命名,可增加代码的可读性。

 

〖建议1-2-3〗尽量避免在注释中使用缩写,特别是不常用缩写。

说明:在使用缩写时,应对缩写进行必要的说明。


 

2    命名规则

好的命名规则能极大地增加可读性和可维护性。同时,对于一个有上百个人共同完成的大项目来说,统一命名约定也是一项必不可少的内容。本章对程序中的所有标识符(包括包、变量名、控件名、常量名、方法名、类名、接口等)的命名做出约定。

三种命名规范说明:

Pascal规范:第1个字符大写,目标名中的每个单词的第1个字母也大写,比如InvoiceNumber或者PrintInvoice。其他的所有字符都小写。

Camel规范:第1个字符不大写,但目标名中的每个单词的第1个字母大写,比如,invoiceNumber。其他的所有字符都小写。

匈牙利规范:在目标名中加入表示类型的前缀,如strName。

2.1  结构命名

规约:

包命名必须以com.umk开始,后面跟有项目名称(或者缩写),再后面为模块名或层级名称。  如:com.umk.项目缩写.模块名  com.umk.nloc.bookmark

如:com.umk.项目缩写.层级名  com.umk.nloc.activities

 

2.2  方法&参数命名

 

【规则2-1】标识符要采用英文单词或其组合,便于记忆和阅读,切忌使用汉语拼音来命名。

说明:标识符应当直观且可以拼读,可望文知义,避免使人产生误解。程序中的英文单词一般不要太复杂,用词应当准确。

 

【规则2-2】标识符只能由26个英文字母,10个数字及下划线的一个子集来组成,并严格禁止使用连续的下划线。用户定义的标识符下划线不能出现在标识符的头尾,数字也不能出现在标识符的头部。

说明:这样做的目的是为了使程序易读。因为variable_name和variable__name很难区分,下划线符号‘_’若出现在标识符头或结尾,容易与不带下划线‘_’的标识符混淆。

 

【规则2-3】标识符应当使用完整的英文描述,标识符的命名应当符合“min-length && max-information”原则,谨慎使用缩写。

说明:对于标识符应当使用完整的英文进行描述,对于整个描述较长的,可对单词进行缩略。较短的单词可通过去掉“元音”形成缩写,较长的单词可取单词的头几个字母形成缩写,一些单词有大家公认的缩写,常用单词的缩写必须统一。协议中的单词的缩写与协议保持一致。对于某个系统使用的专用缩写应该在某处做统一说明。设计命名中应该慎用缩写命名。如要采用,则应采用统一的缩略规则,并且在代码的相应部分统一采用缩写。例如,采用num作为number的缩写,那么在整个代码中应该始终使用该缩写。在使用缩写时,在使用缩写时,应该按着专业术语的要求大小写,例如,System.IO,而不是System.Io。

正例:如下单词的缩写能够被大家认可:

temp 可缩写为tmp;

flag 可缩写为flg;

statistic 可缩写为  stat ;

increment 可缩写为inc;

message 可缩写为msg;

 

以下是一些常用缩写:

常用词

缩写

Argument

arg

Buffer

buf

Clear

clr

Clock

clk

Compare

cmp

Configuration

cfg

Context

ctx

Delay

dly

Device

dev

Disable

dis

Display

disp

Enable

en

Error

err

Function

fnct

Hexadecimal

hex

Initialize

init

Mailbox

mbox

Manager

mgr

Maximum

max

Message

msg

Minimum

min

Multiplex

mux

operatingsystem

OS

Parameter

param

Previous

prev

Priority

prio

Read

rd

Ready

rdy

Register

reg

Schedule

sched

Semaphore

sem

Stack

stk

Synchronize

sync

Timer

tmr

Trigger

trig

Write

wr

 

 

【规则2-4】采用应用领域相关的术语来命名。

说明:软件开发人员应注意软件用户的一些约定术语,不应当随意的创造术语,这会降低软件的易用性。

 

【规则2-5】程序中不要出现仅靠大小写区分的相似的标识符。

说明:命名时应避免采用几乎相同的名称。例如,变量名称persistentObject和persistentObjects不应当同时运用;anSqlDatabase和anSQLDatabase也不应同时使用。

 

【规则2-6】用正确的反义词组命名具有互斥意义的变量或相反动作的函数等。

说明:下面是一些在软件中常用的反义词组。

add / remove ; begin / end; create / destroy ;insert / delete;

first / last ; get / set;    increment / decrement ; put / get;

add / delete; lock / unlock;open / close; min / max;

old / new ;start / stop;next / previous;source / target;

show / hide ; send / receive ;source / destination     ;cut / paste    ;

up / down

【规则2-7】类名和接口使用类意义完整的英文描述,每个英文单词的首字母使用大写、其余字母使用小写的大小写混合法。

正例:

      OrderInformation,CustomerList

 

【规则2-8】属性名使用意义完整的英文描述,第一个单词的字母使用小写,剩余单词首字母大写其余字母小写的大小写混合法。属性名不能与方法名相同。

正例:

private String customerName;

private int orderNumber;

 

【规则2-9】方法名使用类意义完整的英文描述:第一个单词的字母使用小写、剩余单词首字母大写其余字母小写的大小写混合法。

正例:

      privatevoidinsertCustomer();

 

【规则2-10】方法中,存取属性的方法采用set和 get方法,动作方法采用动词和动宾结构。

格式

get+ 非布尔属性名()

is+ 布尔属性名()

set+ 属性名()

动词()

动词 + 宾语()

正例:

public String getType();

publicbooleanisFinished();

public void setVisible(boolean);

public void show();

public voidaddKeyListener(Listener);

 

【规则2-11】常量名使用全大写的英文描述,英文单词之间用下划线分隔开,并且使用 static final修饰。

正例:

      publicstaticfinal int MAX_VALUE = 1000;

 

〖建议2-12〗非静态,非公开成员变量 添加m前缀,以便于同参数,变量相区分。

正例:

private String mCustomerName;

private int mOrderNumber;

〖建议2-13〗静态成员变量 添加s前缀。

正例:

private static String sCustomerName;

private static int sOrderNumber;

〖建议2-14〗常用组件类的命名以组件名加上组件类型名结尾。

正例:

Application类型的,命名以App 结尾——MainApp

Frame类型的,命名以Frame 结尾——TopoFrame

〖建议2-4〗含有集合意义的属性命名,尽量包含其复数的意义。

正例:

customers,  orderItems

〖建议2-15〗变量声明应该只放在代码段的开始部分。最好不要到使用时才声明变量。对象类变量在函数体结束后,手工设置为null值,以利于资源的回收。

2.3   Android命名

2.3.1   layout命名

规约:layout xml 的命名必须以 全部单词小写,单词间以下划线分割,并且使用名词或名词词组,即使用 模块名_功能名称 来命名。

如:knowledge_gained_main.xmlà正确

如:list_book.xmlà错误!

1contentview命名:activity_功能模块.xml

例如:activity_main.xmlactivity_more.xml

2Dialog命名:dialog_描述.xml

      例如:dlg_hint.xml

2PopupWindow命名:ppw_描述.xml

      例如:ppw_info.xml

3. 列表项命名listitem_描述.xml

      例如:listitem_city.xml

4.包含项:include_模块.xml

      例如:include_head.xmlinclude_bottom.xml

 

 

2.3.2   id 命名

〖建议2-3-2〗layout中的id采用以下命名模式:

view缩写_模块名称_view的逻辑名称

说明:view的缩写详情如下

ListView:     lv

Button:           btn

正例:

@+id/lv_appstore_applist

反例:

@+id/ListView01

 

2.3.3   资源命名

规约:layout中所使用的所有资源(如drawable,style等)命名必须以全部单词小写,单词间以下划线分割,并且尽可能的使用名词或名词组,即使用前缀_模块_描述 来命名。如果为公共资源,如分割线等,则直接用描述来命名

如:menu_icon_navigate.png à正确

如:某分割线:line.png  或 separator.png à正确

1.       静态图片前缀_模块、前缀_模块_描述

例如:bg_main.pngic_main_search.png

2.       动态图片前缀_模块_描述_状态、前缀_描述_状态

             例如:btn_film_buy_n.pngbtn_film_buy_p.pngbtn_back_n.png

      如果有多种形态如按钮等除外如btn_film_buy.xmlselector

 

2.3.4  资源缩写说明

  

前缀

说明

ic --icon

主要用于布局和子布局的图标

bg--background

主要用于布局和子布局的背景

di--divider

主要用于分隔线,不仅包括Listview中的还包括普通布局中的线

sl--selector

主要用于某一view多种状态,listview 按钮等

cl--color

主要用于颜色值

bt--button

主要用于按钮的表示,有时我们会在icbt之间犹豫,简单的区分即是功能视图,如果一个view执行的时back或者confirm或者cancel的功能,则命名上则应该使用bt

 

后缀

说明

unit

在使用xmltilemode来配图片时,element图片使用此后缀

nor

图片的状态,代表普通状态

hl

图片的状态,代表高亮状态

press

图片的状态,代表按下状态

select

图片的状态,代表其所占的view被选中

unselect

图片的状态,代表其所占的view没有被选中

 

 

组件名称对照表

 

组件名称

简写

组件名称

简写

Button

Btn(btn)

RadioButton

Rbtn(rbtn)

ImageButton

Ibtn(ibtn)

TextView

Tv(tv)

ImageView

Iv (iv)

ListView

Lv(lv)

ProgressBar

Pbar(pbar)

EditText

Edtv(et)

ScrollView

Sclv(scly)

CheckBox

Chk(chk)

RelativeLayout

Rlyt(rlyt)

LinearLayout

Llyt(llyt)

TableLayout

Tlyt(tlyt)

AbsoluteLayout

ALyt(alyt)

FrameLayout

Flyt(flyt)

 

 

 

2.3.5  字符串命名

最好不要跟titledialogbutton等东西关系起来,直接用相同英文含义就可以了,如果下:

<stringname="ok">确定</string>

<string name="welcome_to_use">欢迎使用</string>

再举一些不好的例子,如下<string name="menu_ok ">确定</string>

 

 

2.3.6  控件命名

控件缩写_描述

例如:TextViewtv_nameButton btn_buyLinearLayoutllyt_body;

 

2.3.7   类命名

功能模块Activity.class  功能模块Service.class

如:MainActivity.class  HuaFuBaoActivity.classAppUpgradeService.class

 

3    Android建议

 Android下的开发基本可沿用Java下的编码规范,这里只是一些命令规范和日志的使用做一些补充。

 

〖建议3-1〗使用日志时,不重要的信息定义在debug等级或者info等级,较为严重的情况把日志定义的warn等级和error等级。正常情况下尽量不使用System.out.println();作为日志的输出

 

〖建议3-2〗数据一定要效验,例如

字符型转数字型,如果转换失败一定要有缺省值;

服务端响应数据是否有效判断

 

〖建议3-3〗如果所开发的为通用组件,为避免冲突,将drawable/layout/menu/values目录下的文件名增加前缀

 

〖建议3-4〗使用button+activitgroup实现tab效果时,使用Button.setSelected(true),确保按钮处于选择状态,并使activitygroup的当前activity与该button对应

 

〖建议3-5〗如果多个Activity中包含共同的UI处理,那么可以提炼一个CommonActivity,把通用部分叫由它来处理,其他activity只要继承它即可

 

〖建议3-6〗activity中在一个View.OnClickListener中处理所有的逻辑

 

〖建议3-7〗不要重用父类的handler,对应一个类的handler也不应该让其子类用到,否则会导致message.what冲突

 

〖建议3-8〗单元测试(逻辑测试、界面测试)

 

〖建议3-9〗Log(系统名称 模块名称 接口名称,详细描述)

 

〖建议3-10〗使用静态变量方式实现界面间共享要慎重

 

〖建议3-11〗引用第三方库要慎重,避免应用大容量的第三方库,导致客户端包非常大

 

〖建议3-12〗服务端可以实现的,就不要放在客户端

 

〖建议3-13〗styles.xml:将layout中不断重现的style提炼出通用的style通用组件,放到styles.xml中;

 

〖建议3-12〗服务端可以实现的,就不要放在客户端

 

〖建议3-12〗服务端可以实现的,就不要放在客户端

 

 

 

 

****************************************

以下内容和规范无关

****************************************

 

4    Eclipse配置方法

 

1.     注释模板

在eclipse 的preferences 中,选择 java à code style àcode Template

1. 添加文件创建日志模板

2.设置类注释模板

 

2.    导入方法

在eclipse 的preferences 中,选择 java à code style àcode Template 中选择 Import,选择附件中的文件。

但是注意修改类注释文件注释的作者名称为自己的!

 

3.    格式化模板

在eclipse 的preferences 中,选择 java à code style àformatter 中选择 Import,选择附件中的文件。

4.    XML格式化

在eclipse 的preferences 中,选择 xml à xml files à xml editor 中 做如下设置

 

 

 

5    21种代码的坏味道

应该在编程中尽量避免这21种“坏味道”。

1.   Duplicated Code

代码重复几乎是最常见的异味了。他也是Refactoring 的主要目标之一。代码重复往

往来自于copy-and-paste 的编程风格。

2.   Long method

它是传统结构化的“遗毒“。一个方法应当具有自我独立的意图,不要把几个意图

放在一起。

3.   Large Class

大类就是你把太多的责任交给了一个类。这里的规则是One Class One Responsibility。

4.   Divergent Change

一个类里面的内容变化率不同。某些状态一个小时变一次,某些则几个月一年才变一次;某些状态因为这方面的原因发生变化,而另一些则因为其他方面的原因变一次。面向对象的抽象就是把相对不变的和相对变化相隔离。把问题变化的一方面和另一方面相隔离。这使得这些相对不变的可以重用。问题变化的每个方面都可以单独重用。这种相异变化的共存使得重用非常困难。

5.   Shotgun Surgery

这正好和上面相反。对系统一个地方的改变涉及到其他许多地方的相关改变。这些变化率和变化内容相似的状态和行为通常应当放在同一个类中。

6.   Feature Envy

对象的目的就是封装状态以及与这些状态紧密相关的行为。如果一个类的方法频繁用get 方法存取其他类的状态进行计算,那么你要考虑把行为移到涉及状态数目最多的那个类。

7.   Data Clumps

某些数据通常像孩子一样成群玩耍:一起出现在很多类的成员变量中,一起出现在许多方法的参数中…..,这些数据或许应该自己独立形成对象。

8.   Primitive Obsession

面向对象的新手通常习惯使用几个原始类型的数据来表示一个概念。譬如对于范围,他们会使用两个数字。对于Money,他们会用一个浮点数来表示。因为你没有使用对象来表达问题中存在的概念,这使得代码变的难以理解,解决问题的难度大大增加。好的习惯是扩充语言所能提供原始类型,用小对象来表示范围、金额、转化率、邮政编码等等。

9.   Switch Statement

基于常量的开关语句是OO 的大敌,你应当把他变为子类、state 或strategy。

10.Parallel Inheritance Hierarchies

并行的继承层次是shotgun surgery 的特殊情况。因为当你改变一个层次中的某一个类时,你必须同时改变另外一个层次的并行子类。

11.Lazy Class

一个干活不多的类。类的维护需要额外的开销,如果一个类承担了太少的责任,应当消除它。

 

12.Speculative Generality

一个类实现了从未用到的功能和通用性。通常这样的类或方法唯一的用户是testcase。不要犹豫,删除它。

13.Temporary Field

一个对象的属性可能只在某些情况下才有意义。这样的代码将难以理解。专门建立一个对象来持有这样的孤儿属性,把只和他相关的行为移到该类。最常见的是一个特定的算法需要某些只有该算法才有用的变量。

14.Message Chain

消息链发生于当一个客户向一个对象要求另一个对象,然后客户又向这另一对象要求另一个对象,再向这另一个对象要求另一个对象,如此如此。这时,你需要隐藏分派。

15.Middle Man

对象的基本特性之一就是封装,而你经常会通过分派去实现封装。但是这一步不能走得太远,如果你发现一个类接口的一大半方法都在做分派,你可能需要移去这个中间人。

16.Inappropriate Intimacy

某些类相互之间太亲密,它们花费了太多的时间去砖研别人的私有部分。对人类而言,我们也许不应该太假正经,但我们应当让自己的类严格遵守禁欲主义。

17.Alternative Classes with Different Interfaces

做相同事情的方法有不同的函数signature,一致把它们往类层次上移,直至协议一致。

18.Incomplete Library Class

要建立一个好的类库非常困难。我们大量的程序工作都基于类库实现。然而,如此广泛而又相异的目标对库构建者提出了苛刻的要求。库构建者也不是万能的。有时候我们会发现库类无法实现我们需要的功能。而直接对库类的修改有非常困难。这时候就需要用各种手段进行Refactoring。

19.Data Class

对象包括状态和行为。如果一个类只有状态没有行为,那么肯定有什么地方出问题了。

20.Refused Bequest

超类传下来很多行为和状态,而子类只是用了其中的很小一部分。这通常意味着你的类层次有问题。

21.Comments

经常觉得要写很多注释表示你的代码难以理解。如果这种感觉太多,表示你需要Refactoring。

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值