(review代码,check代码需要注意的规范,需牢记!)
目录
1.前言
Java代码规范以SUN的标准Java代码规范为基础;
2.标识符命名规范
统一/简洁/定义规则(骆峰法则)
2.1统一
统一是指,对于同一个概念,在程序中用同一种表示方法,比如对于供应商,既可以用supplier,也可以用provider,但是我们只能选定一个使用,至少在一个Java项目中保持统一。统一是作为重要的,如果对同一概念有不同的表示方法,会使代码混乱难以理解。即使不能取得好的名称,但是只要统一,阅读起来也不会太困难,因为阅读者只要理解一次。
2.2简洁
简洁是指,在统一和达意的前提下,用尽量少的标识符。如果不能达意,宁愿不要简洁。比如: theOrderNameOfTheTargetSupplierWhichIsTransfered 太长, transferedTargetSupplierOrderName则较好,但是transTgtSplOrdNm就不好了。省略元音的缩写方式不要使用,我们的英语往往还没有好到看得懂奇怪的缩写。
2.3骆峰法则
Java中,除了包名,静态常量等特殊情况,大部分情况下标识符使用骆驼法则,即单词之间不使用特殊符号分割,而是通过首字母大写来分割。比如: SupplierName, addNewContract,而不是 supplier_name, add_new_contract。
- 包名:使用小写字母如
com.wshh.pactera
,不要com.wshh.Pactera。
为了唯一建议使用公司的域名反向表示作为制定模块的包名; - 类名:类名要首字母大写,比如 SupplierService, PaymentOrderAction;不要 supplierService, paymentOrderAction.
- 后缀:类名往往用不同的后缀表达额外的意思,如下表:
后缀名 | 意义 | 举例 |
Service | 表明这个类是个服务类,里面包含了给其他类提同业务服务的方法 | PaymentOrderService |
Impl | 这个类是一个实现类,而不是接口 | PaymentOrderServiceImpl |
Inter | 这个类是一个接口 | LifeCycleInter |
Dao | 这个类封装了数据访问方法 | PaymentOrderDao |
Action | 直接处理页面请求,管理页面逻辑了类 | UpdateOrderListAction |
Listener | 响应某种事件的类 | PaymentSuccessListener |
Event | 这个类代表了某种事件 | PaymentSuccessEvent |
Servlet | 一个Servlet | PaymentCallbackServlet |
Factory | 生成某种对象工厂的类 | PaymentOrderFactory |
Adapter | 用来连接某种以前不被支持的对象的类 | DatabaseLogAdapter |
Job | 某种按时间运行的任务 | PaymentOrderCancelJob |
Wrapper | 这是一个包装类,为了给某个类提供没有的能力 | SelectableOrderListWrapper |
Bean | 这是一个POJO | MenuStateBean |
- 方法名(函数)
首字母小写,如 addOrder() 不要 AddOrder()动词在前,如 addOrder(),不要orderAdd()动词前缀往往表达特定的含义,如下表:
注意:find方法在业务层尽量表达业务含义,比如 findUnsettledOrders(),查询未结算订单,而不要findOrdersByStatus()。 数据访问层,find,update等方法可以表达要执行的sql,比如findByStatusAndSupplierIdOrderByName(Status.PAID, 345)
前缀名 | 意义 | 举例 |
create | 创建 | createOrder() |
delete | 删除 | deleteOrder() |
add | 创建,暗示新创建的对象属于某个集合 | addPaidOrder() |
remove | 删除 | removeOrder() |
init或则initialize | 初始化,暗示会做些诸如获取资源等特殊动作 | initializeObjectPool |
destroy | 销毁,暗示会做些诸如释放资源的特殊动作 | destroyObjectPool |
open | 打开 | openConnection() |
close | 关闭 | closeConnection()< |
read | 读取 | readUserName() |
write | 写入 | writeUserName() |
get | 获得 | getName() |
set | 设置 | setName() |
prepare | 准备 | prepareOrderList() |
copy | 复制 | copyCustomerList() |
modity | 修改 | modifyActualTotalAmount() |
calculate | 数值计算 | calculateCommission() |
do | 执行某个过程或流程 | doOrderCancelJob() |
dispatch | 判断程序流程转向 | dispatchUserRequest() |
start | 开始 | startOrderProcessing() |
stop | 结束 | stopOrderProcessing() |
send | 发送某个消息或事件 | sendOrderPaidMessage() |
receive | 接受消息或时间 | receiveOrderPaidMessgae() |
respond | 响应用户动作 | responseOrderListItemClicked() |
find | 查找对象 | findNewSupplier() |
update | 更新对象 | updateCommission() |
- 局部变量:参数和局部变量名首字母小写,骆驼法则。尽量不要和域冲突,尽量表达这个变量在方法中的意义。
- 静态常量名:全大写用下划线分割,如
public static find String ORDER_PAID_EVENT = "ORDER_PAID_EVENT";
- 枚举:全大写,用下划线分割,如
public enum Events {
ORDER_PAID,
ORDER_CREATED
}
3.代码格式
用空格字符缩进源代码,不要用tab,每个缩进4个空格。
4.注释规范
注释宜少而精,不宜多而滥,更不能误导
命名达意,结构清晰, 类和方法等责任明确,往往不需要,或者只需要很少注释,就可以让人读懂;相反,代码混乱,再多的注释都不能弥补。所以,应当先在代码本身下功夫。
不能正确表达代码意义的注释,只会损害代码的可读性。
过于详细的注释,对显而易见的代码添加的注释,罗嗦的注释,还不如不写。
注释要和代码同步,过多的注释会成为开发的负担
注释不是用来管理代码版本的,如果有代码不要了,直接删除,svn会有记录的,不要注释掉,否则以后没人知道那段注释掉的代码该不该删除
1.块级别注释,单行时用 //, 多行时用 /* .. */。
/*------ start: ------*/
和
/*-------- end: -------*/
包围
如:/*----------start:
订单处理
------- */
//
取得
dao
OrderDao dao = Factory.getDao("OrderDao");
/*
查询订单
*/
Order order = dao.findById(456);
//
更新订单
order.setUserName("uu");
order.setPassword("pass");
order.setPrice("ddd");
orderDao.save(order);
/*----------end:
订单处理
------- */
使用大括号表示注释作用范围的例子:/*----------
订单处理
------- */
{
//
取得
dao
OrderDao dao = Factory.getDao("OrderDao");
/*
查询订单
*/
Order order = dao.findById(456);
//
更新订单
order.setUserName("uu");
order.setPassword("pass");
order.setPrice("ddd");
orderDao.save(order);
}
行内注释用 // 写在行尾
程序员都是懒惰的,不要想着等我完成了功能,再来优化代码的格式和结构,等真的把功能完成,很少有人会再愿意回头调整代码。
7. 使用log而不是System.out.println()
log可以设定级别,可以控制输出到哪里,容易区分是在代码的什么地方打印的,而System.out.print则不行。而且,System.out.print的速度很慢。所以,除非是有意的,否则,都要用log。至少在提交到svn之前把System.out.print换成log。
8. 每个if while for等语句,都不要省略大括号{}
看下面的代码:if (a > b)
a++;
如果在以后维护的时候,需要在a > b 时,把b++,一步小心就会写成:if (a > b)
a++;
b++;
这样就错了,因为无论a和b是什么关系,b++都会执行。 如果一开始就这样写:if (a > b) {
a++;
}
相信没有哪个笨蛋会把b++添加错的。而且,这个大括号使作用范围更明显,尤其是后面那行很长要折行时。
在代码中加入 //TODO: ,大部分的ide都会帮你提示,让你知道你还有什么事没有做。比如:if (order.isPaid()) {
//TODO:
更新订单
}
10. 在需要留空的地方放一个空语句或注释,告述读者,你是故意的
比如:if (!exists(order)) {
;
}
或:
if (!exists(order)) {
//nothing to do
}
比如:if (order.isPaid() == true) {
// Do something here
}
不如写成:if (order.isPaid()) {
//Do something here
}
后者读起来就很是 if order is paid, .... 要比 if order's isPaid method returns true, … 更容易理解
代码嵌套层次达3层以上时,一般人理解起来都会困难。下面的代码是一个简单的例子:public void demo(int a, int b, int c) {
if (a > b) {
if (b > c) {
doJobA();
} else if (b < c) {
doJobB()
}
} else {
if (b > c) {
if (a < c) {
doJobC();
}
}
}
}
减少嵌套的方法有很多:
- 合并条件
- 利用 return 以省略后面的else
- 利用子方法
比如上例,合并条件后成为:public void demo(int a, int b, int c) {
if (a > b && b > c) {
doJobA();
}
if (a > b && c > b) {
doJobB();
}
if (a <= b && c < b && a < c) {
doJobC();
}
}
如果利用return 则成为:public void demo(int a, int b, int c) {
if (a > b) {
if (b > c) {
doJobA();
return;
}
doJobB()
return;
}
if (b > c) {
if (a < c) {
doJobC();
}
}
}
利用子方法,就是将嵌套的程序提取出来放到另外的方法里。
希望对后面来文思海辉的小同志一点帮助!