fWX228941 / project

all by myself
1 stars 0 forks source link

Java/Android编码规范 #2

Open fWX228941 opened 5 years ago

fWX228941 commented 5 years ago

1前言

每个人的编码习惯和代码风格都不尽相同,不说那些缺乏良好编码习惯的开发人员,就连那些已经养好良好编码习惯的人员,很多方面都会存在差异,如若不约定好统一规范,久了肯定乱,尤其是在团队开发中非常明显,因此提前定义好规范,统一编程风格是必须的,接下来我将以优先级的次序依次展开详解。

2命名规范

好的命名,表词达意,意图明显,阅读起来干净利落,一目了然,赏心悦目,甚至都不需要查看多余的注释,即使新手也可迅速上手,其重要程度使我将其优先级直接提到了最高。

2.1.通用原则:

 1.1..命名尽量意思表达准确,用全英文名,避免缩写。

以变量名为例(同样适用于为类,包,文件以及其他的编程实体命名)取名要完全,准确地描述出该变量所代表的事物,可读易懂,这就是最佳的变量名,避免晦涩难懂的缩写,请善用百度翻译。 比如:ListView 有人喜欢缩写为lv,TextView缩写为tv,含糊不清,是很不好的缩写方式。 比如:要表达“当前日期”,好的命名“currentDate” 直白明了,坏的命名“current 不知道当前是什么”,“date 表示所有日期,并非特指当前日志”。

 1.2.名字长度:可以长但绝不允许太短,确保名字含义足够清晰。

短的变量名作用于局部变量和循环变量,比如i/j/k常常用作于循环下标或者数组下标,代表一个临时数据,作用域也非常有限,单循环内的变量约定俗成i,j,k,深入人心,我们也一并继承过来, 循环外或者多嵌套循环变量需要取一个更有意义的名字。

 1.3.计算量的限定词,请放在修饰名的后面,Total,Sum,Average,Max,Min。这样是为了把变量名中最重要的部分放在最前面。

比如:要表达“总支出”expenseTotal>totalExpense 尽管语义上是等价的。

 1.4.缩写策略:还是建议全写,适当的去掉每个单词的几个字母,保留每个音节中最引人注意的发音,避免歧义。

2.2.包名:包名具有框架级的意义,不仅可以描述出此包的核心功能还有代码路径,如若没有特殊说明此后的项目统一以com.caltta.xx的方式命名,包名要求全部小写。

1

2.3.类名:类是封装相关操作与属性的集大成者,其命名以功能名+组件名的方式,功能名尽量全写,除非单词特别长可适当缩写,首字母要求大写,类名包含的逐个单词其第一个字母大写,其他部分小写(驼峰方式)。 2

组件名 示例&说明
Activity/Fragment PDTDialerFragment.java  界面
Service PDTDownloadSercice.java 服务
Receiver PDTGlobalReceiver.java  广播
View PDTDialpadView.java自定义视图
Util/Helper PDTAlertAudioUtil.java工具
Handler PDTCallHandler.java 业务
Thread/Task PDTSyncTask 线程
Provider/Preference PDTChannelProvider 数据库
Entity/Info PDTMessageEntity.java 实体
Constants/Para/Data/Define PDTConstants,java 常量
CallBack/Listener/observer PDTGlobalObserver.java 监听回调
Adapter PDTBaseAdapter.java 适配器

2.4.资源文件名:以功能名_包名的方式统一命名,中间以_隔开,我们以eclipse为参考,使用android studio等其他开发工具的同上述原理,不再赘述。

包名 示例&说明
anim push_bottom_in_anim.xml  按钮动画
color setttings_text_color.xml 设置界面文本颜色
drawable item_contacs_selector.xml  联系人列表项样式
layout activity_channel_info_layout.xml 信道详情界面
xml settings_digit_preference.xml  设置数字常规界面

2.5.方法名:全称以驼峰方式来命名,首字母要求小写,方法名包含的逐个单词其第一个字母大写,其他部分小写,并附上作者和注释。

3

2.6.变量名:成员/全局变量以m开头,局部/临时变量/参数小写开头全称驼峰即可,常量固定大写,所有非字面含义的数字以常量方式命名,不得出现magic number,并且要求写上注释,优先英文。 2.7 接口名称:命名以I开始。

3变量

3.1.在声明全局变量的时候初始化,临时变量在第一次使用的位置初始化 4

3.2计数器功能的临时变量以及声明为static的共享全局变量注意检查是否需要重新初始化。 成员变量其生命周期从new对象实例化开始到被GC回收为止,而static静态变量其生命周期与应用application保持一致,无视对象化,具有最长生命周期。

3.3.尽可能缩短变量的存活时间,缩小其作用域,当对变量的作用域犹豫不决时,请选择该变量所具有的最小的作用域,能用局部变量的地方避免使用全局变量。 局限于某个特定的循环 > 子程序 > private 成员变量 > protected 继承变量 > public 共享变量 > public static 全局变量

3.4.变量也遵循单一原则,即每个变量只用于单一用途,单职责,禁止单变量多用途,滥用会导致混合耦合。 同时确保使用了所有已经声明的变量,在eclipse中会自动检测从未被使用过的变量,为其贴上黄色标签。

4类

4.1.单一职责:类的设计要遵循单一职责原则,即就一个类而言,应该仅有一个引起它变化的原因,至于如何划分并不总是那么清晰,很多时候需要靠个人经验来界定,这里提供一些原则供参考。

4.3.扩展开发:当业务需求发生变化时,应该尽量通过扩展的方式来扩展实现,而不是通过修改已有的代码来实现,除非是因为代码本身错误,即对软件中的对象(类,模块,函数)对扩展开放,对修改封闭。

4.4.继承:利用继承来设计基类,抽象出公共属性和方法,以此达到代码复用的程度,继承是一种高耦合的关系,颇具侵略性,因为只要继承就必须拥有父类的所有属性和方法,所以不是父子关系的两个类不要设计为继承关系,其判断依据为是不是“is a 是一个”的关系。

4.5.面向接口编程:最大化对外隐藏实现细节,类之间不发生直接的依赖关系,其依赖关系通过接口或者抽象类产生,并且是尽量最小化接口,最典型的就是观察者模式在模块(类之间)通信方面的应用,如果两个类之间直接依赖于细节,那么它们之间就有了直接的耦合,当具体实现发生变化时,意味着要同时修改依赖者的代码。

4.6.低耦合:一个类应该对自己需要耦合或调用的类知道得最少,服务端类的内部如何实现与调用者或者客户端类没有关系。

5子程序

创建高质量的子程序的一些指导原则:

6格式

7注释

8类型对象和数据结构

8.1.避免不同类型的值进行比较。 8.2.在含有复杂判断条件的if语句中,用一个布尔函数来对程序提供说明,大大提供可读性。 8.3.性能上考虑,android不推荐用emu 枚举类型,使用@IntDef @StringDef来代替 8.4.禁止使用magic number 使用具名常量代替,使用具名常量是一种将程序“参数化”的方法——把程序中可能变化的一个方面写为一个参数,当需要对其修改时,只改变一处就可以了。 8.5.对于数组类型,下标越界是常见错误,用arrayList这样的容器取代数组,检查数组的边界点,确认所有的数组下标没有超出数组的边界。

9语句 9.1.顺序相关的语句:如果语句之间存在依赖关系,并且这些关系要求你把语句按照一定的顺序加以排列,那么请设法使得这些依赖关系变得明显,不要过分无参封装成几个有依赖关系的方法。

9.2.顺序无关的语句:合理组织代码,要让程序易于自上而下阅读。

9.3.语句的相关性:所谓相关性是指它们都处理了相同的数据,执行了相似的任务,或者具有某种执行顺序上的依赖关系,因此要把相关的语句放在一起,这也是把它们重构成独立子程序的信号。

9.4.条件语句: 1)把主流程场景放在if后面处理,异常处理或者不常见场景放在else后面,即把决策的结果代码放在尽可能靠近决策位置。 2)避免空的if语句,简单地对if语句中的谓词作否定!boolean,把else子句中的代码移到if子句中来,并且去掉else子句就可以了。 3)对于多个判断if else语句,把最常见的情况放在最前面。确保所有的场景都考虑到,最后的else 语句用来捕获异常和你没有考虑的情况,这种消息是给程序员而非最终用户看的。 4)对于switch case语句按执行频率排列case子句,把正常的情况放在前面,case语句适用于简单的操作,如果是复杂的操作请封装成一个子程序,default子语句来检查错误。 5)if嵌套语句不要超过3次,一个有效减少嵌套的手段是使用return语句。在某些子程序中,一旦知道了答案,那么就使用return语句来返回到调用方子程序。

9.5.循环语句: 1)把循环看做是一个黑盒子,外围程序只知道它的控制条件,却不知道它的内容,需要把初始化的代码紧放在循环前面,避免分散在各处。 提前退出循环:break,程序会从循环后面的第一条语句开始执行下去。而continue是if else的一种缩写,阻止循环体剩余部分的执行而从循环的下一次迭代的开始位置继续执行。

10 错误处理

10.1.谨慎使用try catch finally来捕获异常,仅仅在真正异常的情况下,即编码无法解决的情况下才使用异常机制,如果某种的错误场景可以在局部处理,就应该在局部处理掉它,异常机制只处理那些不仅罕见甚至永远都不该发生的情况,不应该用于正常的控制流。 10.2.优先使用标准异常

异常 使用场景
IllegalArgumentException 调用方传递的参数值非法,不合适
IllegalStateException 被调用对象在没有正确初始化之前,调用方就企图使用这个对象,说明这个被调用的对象状态非法
NullPointerException 空指针
IndexOutOfBoundsExceptioin 数组下标越界
ConcurrentModificationException 在禁止开发修改的情况下,检查到对象的并发修改
UnsupportedOperationException 不支持的用户操作

5

Checked Exception 属于非运行时异常,必须添加try catch 或者throw异常。

11结语

最重要的并不在于规范怎么定义,而是在于规范的严格执行。如果规范定义好了,但却不遵守,那规范就等于形同虚设,因此规范一旦设定,就要严格执行。