前言:编码规范的重要性
什么是编码规范?
在讲编码规范的重要性之前,我们得先明白,什么叫做编码规范。在说代码规范之前,我们谈谈什么是路,鲁迅的《故乡》 原文结尾提到:“其实地上本没有路,走的人多了,也便成了路。”代码规范正如世上的路,代码原本只是为了实现某些功能,你可以任意的去写,但是大家慢慢的,习惯性的,在程序中都用同一种表示方法来实现某一个功能,于是就有了代码规范,然后所有的程序员都按照这个规范去写。比如秦始皇车九尺,书同文,就是为了做一个全国统一的规范,当时所有的修路工、读书人,都得按照这个规范去做。编码规范,就是做一个程序员之间统一的规范,方便互相之间的代码阅读及理解。
编码规范的重要性
这里采用举反例的方式来证明编码规范的重要性。
1 | public class Demo{public static void main(String[] args){Scanner s=new Scanner(System.in);String ss=s.nextLine();if("exit".equalIgnoreCase(s)){System.out.println("开始退出程序...");System.exit;}}} |
这样完成了一个简单的代码,你能轻松的对这段代码进行阅读吗?我甚至可以告诉你,这段代码有一处错误,你能第一时间发现吗?
但如果把代码按照以下格式编写,你就能很直观的看出问题所在。
1 | public class Demo { |
没错,在第五行 if 语句判断中,使用了 scanner 去判断是否输入了 exit ,这显然是错误的,应该使用 str 变量去进行判断。
正文:编码规范的标准
标识符的命名规范
概述
标识符的命名⼒求做到统⼀、达意和简洁。
统一
统⼀是指,对于同⼀个概念,在程序中⽤同⼀种表⽰⽅法,⽐如对于供应商,既可以⽤supplier,也可以⽤provider,但是我们只能选定⼀
个使⽤,⾄少在⼀个Java项⽬中保持统⼀。统⼀是作为重要的,如果对同⼀概念有不同的表⽰⽅法,会使代码混乱难以理解。即使不能取得
好的名称,但是只要统⼀,阅读起来也不会太困难,因为阅读者只要理解⼀次。
达意
达意是指,标识符能准确的表达出它所代表的意义,⽐如: newSupplier, OrderPaymentGatewayService等;⽽ supplier1, service2,idtts等则不是好的命名⽅式。准确有两成含义,⼀是正确,⼆是丰富。如果给⼀个代表供应商的变量起名是 order,显然没有正确表达。同样的,supplier1, 远没有targetSupplier意义丰富。
简洁
简洁是指,在统⼀和达意的前提下,⽤尽量少的标识符。如果不能达意,宁愿不要简洁。⽐如:theOrderNameOfTheTargetSupplierWhichIsTransfered 太长, transferedTargetSupplierOrderName则较好,但是transTgtSplOrdNm就不好了。省略元⾳的缩写⽅式不要使⽤,我们的英语往往还没有好到看得懂奇怪的缩写。
驼峰命名法
小驼峰命名法
小驼峰命名法指首字母小写,后续每一个单词首字母保持大写。例如 compareTwoObjects。
大驼峰命名法
大驼峰命名法指首字母大写, 后续每一个单词首字母保持大写。例如 PlayerLoginInListener。
英文与拼音
尽量使⽤通俗易懂的英⽂单词,如果不会可以向万能的度娘求助,实在不⾏则使⽤汉语拼⾳,避免拼⾳与英⽂混⽤。⽐如表⽰归档,⽤archive⽐
较好, ⽤pigeonhole则不好,⽤guiDang尚可接受。
包名
包名应当保持使用小写字母,并尽可能使用自己的域名来命名。例如我的域名是microhand.work,而我的网名是SanseYooyea,所以我的包名一般是work.microhand.sanseyooyea,此处域名应当反写。这么做的原因是为了避免包名重复,避免一些问题的产生。
类名
类名应当采用大驼峰命名法。
后缀
类名往往⽤不同的后缀表达额外的意思,如下表:
后缀名 | 意义 | 举例 |
---|---|---|
Service | 表明这个类是个服务类,⾥⾯包含了给其他类提同业务服务的⽅法 | PaymentOrderService |
Impl | 这个类是⼀个实现类,⽽不是接⼝ | PaymentOrderServiceImpl |
Inter | 这个类是一个接口 | LifeCycleInter |
Dao | 这个类封装了数据访问方法 | PaymentOrderDao |
Action | 直接处理页⾯请求,管理页⾯逻辑类 | UpdateOrderListAction |
Listener | 对于某种事件的监听器 | PlayerLeaveListener |
Event | 表示某种事件的类 | PlayerLeaveEvent |
Servlet | ⼀个Servlet | PaymentCallbackServlet |
Factory | ⽣成某种对象⼯⼚的类 | PaymentOrderFactory |
Adapter | ⽤来连接某种以前不被⽀持的对象的类 | DatabaseLogAdapter |
Job/Task | 某种按时间运⾏的任务类 | PaymentOrderCancelJob/Task |
Wrapper | 这是⼀个包装类,为了给某个类提供没有的能⼒ | SelectableOrderListWrapper |
Bean | 一个POJO | MenuStateBean |
方法名
方法名应当采用小驼峰命名法
前缀
动词前缀往往表达特定的含义,如下表:
前缀名 | 意义 | 举例 |
---|---|---|
create | 创建 | createOrder() |
delete | 删除 | deleteOrder() |
add | 新增 | addOrder() |
remove | 删除 | removeOrder() |
init/initialize | 初始化 | initObjectPool() |
destory | 销毁 | destoryObjectPool() |
open | 打开 | openConnection() |
close | 关闭 | closeConnection() |
read | 读取 | readUserName() |
write | 写入 | writeUserName() |
get | 获取 | getUserName() |
set | 设置 | setUserName() |
prepare | 准备 | prepareOrderList() |
copy | 复制 | copyCustomerList() |
modify | 修改 | modifyCustomerList() |
calculate | 计算 | calculateCommission() |
do | 执行某个过程或流程 | doCancelOrderJob() |
dispatch | 判断流程转向 | dispatchUserRequest() |
start | 开始 | startOrderProcessing() |
stop | 结束 | stopOrderProcessing() |
send | 发送某个消息或事件 | sendOrderPaidMessage() |
receive | 接受某个消息或事件 | receiveOrderPaidMessage() |
respond | 相应用户动作 | responseClickPayButton() |
find | 查找对象 | findNewSupplier() |
update | 更新对象 | updateSupplierList() |
静态常量与枚举类变量
所有字母应保持大写,每个单词间用_分割,例如:ORDER_PAID_EVENT
普通变量
普通变量名应当采用小驼峰命名法
注释的规范
概述
注释宜少⽽精,不宜多⽽滥,更不能误导。
命名达意,结构清晰,类和⽅法等责任明确,往往不需要,或者只需要很少注释,就可以让⼈读懂;相反,代码混乱,再多的注释都
不能弥补。所以,应当先在代码本⾝下功夫。
不能正确表达代码意义的注释,只会损害代码的可读性。
过于详细的注释,对显⽽易见的代码添加的注释,罗嗦的注释,还不如不写。
注释要和代码同步,过多的注释会成为开发的负担。
注释不是⽤来管理代码版本的,如果有代码不要了,直接删除,svn会有记录的,不要注释掉,否则以后没⼈知道那段注释掉的代码该
不该删除。
Java doc
表明类、域和⽅法等的意义和⽤法等的注释,要以javadoc的⽅式来写。Java Doc是给类的使⽤者来看的,主要介绍是什么,怎么⽤等信
息。凡是类的使⽤者需要知道,都要⽤Java Doc 来写。⾮Java Doc的注释,往往是给代码的维护者看的,着重告述读者为什么这样写,如
何修改,注意什么问题等。