注:参考了《阿里巴巴Java开发手册》 阿里编码规范考试认证:https://edu.aliyun.com/certification/cldt02 一、命名规范
- 包名,类名,方法名,变量名 (重要)
A. 包名:包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。例如:com.yoc.sale.business.report
不能出现大写或者下划线:com.yoc.sale.businessReport 或者 com.yoc.sale.business_report
B. 类名:
(1) 类名使用 UpperCamelCase 风格,但以下情形例外:DO / BO / DTO / VO / AO/ PO / UID 等。
正例:JavaServerlessPlatform / UserDO / XmlService / TcpUdpDeal / TaPromotion
反例:javaserverlessplatform / UserDo / XMLService / TCPUDPDeal / TAPromotion
(2) 抽象类命名使用 Abstract 或 Base 开头;异常类命名使用 Exception 结尾;测试类命名以它要测试的类的名称开始,以 Test 结尾。
C: 方法名:必须遵从驼峰形式, 最好以 动词 + 名词的方式。例如: 根据ID获取用户信息 -> getUserInfoById(), 以get,resovle,handle,to,copy,parse等动词开头,一看方法名就知道该方法是干嘛的
D: 变量名:驼峰命名,尽量不用拼音,单词尽量不要缩写,要写全,不要怕长。杜绝完全不规范的缩写,避免望文不知义。
反例:AbstractClass“缩写”命名成 AbsClass;condition“缩写”命名成 condi,此类随意缩写严重降低了代码的可阅读性
POJO类中布尔类型变量都不要加 is 前缀,否则部分框架解析会引起序列化错误。 - 其他
A. 抽象类命名使用 Abstract 或 Base 开头;异常类命名使用 Exception 结尾;测试类命名以它要测试的类的名称开始,以 Test 结尾
B. 常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长. 例如:MAX_STOCK_COUNT
C. 为了防止精度损失,禁止使用构造方法 BigDecimal(double)的方式把 double 值转化为 BigDecimal 对象。优先推荐入参为 String 的构造方法,或使用 BigDecimal 的 valueOf 方法
D. 定义数据对象 DO 类时,属性类型要与数据库字段类型相匹配。
E. 所有整型包装类对象之间值的比较,全部使用 equals 方法比较。
F. Object 的 equals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用equals。
正例:“test”.equals(object);
反例:object.equals(“test”); - 【参考】各层命名规约:
A) Service/DAO 层方法命名规约
1) 获取单个对象的方法用 get 做前缀。
2) 获取多个对象的方法用 list 做前缀,复数形式结尾如:listObjects。
3) 获取统计值的方法用 count 做前缀。
4) 插入的方法用 save/insert 做前缀。
5) 删除的方法用 remove/delete 做前缀。
6) 修改的方法用 update 做前缀。
B) 领域模型命名规约
1) 数据对象:xxxDO,xxx 即为数据表名。
2) 数据传输对象:xxxDTO,xxx 为业务领域相关的名称。
3) 展示对象:xxxVO,xxx 一般为网页名称。
4) POJO 是 DO/DTO/BO/VO 的统称,禁止命名成 xxxPOJO。
二、注释规约
- 所有的类都必须添加创建者和创建日期:作者和时间:@author,@date
/**
* 渠道数据统计-报表控制器
*
* @author Xiang Jiangcheng
* @date 2020/3/6
*/
- 类、类属性、类方法的注释必须使用 Javadoc 规范,使用/*内容/格式,不得使用// xxx 方式。
- 所有的抽象方法(包括接口中的方法)必须要用 Javadoc 注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能
说明:在 IDE 编辑窗口中,Javadoc 方式会提示相关注释,生成 Javadoc 可以正确输出相应注释;在 IDE
中,工程调用方法时,不进入方法即可悬浮提示方法、参数、返回值的意义,提高阅读效率。
说明:如有实现和调用注意事项,请一并说明。
/**
* fetch data by rule id
*
* @param ruleId rule id
* @param page page number
* @param jsonContext json format context
* @return Result<XxxxDO>
*/
Result<XxxxDO> fetchDataByRuleId(Long ruleId, Integer page, String jsonContext);
- 方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/* */注释,注意与代码对齐。
注: 其实还应该给每个文件加上copyright信息,格式如下
/*
* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*/
三、异常
- 开发中,如果某个方法里面有逻辑可能会产生已知的异常,一定要手动catch,并处理,或者往外抛。具体怎么处理看业务
- 有 try 块放到了事务代码中,catch 异常后,如果需要回滚事务,一定要注意手动回滚事务。
- 防止 NPE,是程序员的基本修养,注意 NPE 产生的场景:
1) 数据库的查询结果可能为 null。
2) 远程调用返回对象时,一律要求进行空指针判断,防止 NPE。
所以,如果调用者和被调用者,都应该尽量避免NPE。
例如:A去调用B提供的方法,或者接口。
B定义的方法List<T> getUserList(),返回结果是一个list,如果没有用户信息,那么这个方法是应该返回null呢,还是一个空数组?
所以,A调用B的接口,A自己应该判空,防止NPE。不管B最终返回的是null,还是空数组,都不会报NPE
四、实际开发规约
- Controller层
这一层控制简单的业务逻辑,包括数据校验,不要写太多代码。返回数据类型不能直接是Map,List,应该封装成bean返回, - Service层
这一层,主要做业务逻辑。要求必须有接口和对应的实现类 ,统一继承Mybatis-plus插件的ServiceImpl,统一继承Mybatis-plus插件的ServiceImpl。
注意:所有的覆写方法,必须加@Override 注解。
public interface UserService extends IService<User> {}
impl
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {}
- Mapper层
持久层,复杂数据库的CURD,统一继承Mybatis-plus插件的BaseMapper
/**
* UserRepository, UserDao, UserMapper ?? 这里我们统一命名为xxxMapper,继承mybatis-plus的BaseMapper
* <p>
* 简单的CURD直接用BaseMapper里面封装的方法,一般sql的用注解@select,复杂的写xml
* 用户持久层
*/
@Mapper
public interface UserMapper extends BaseMapper<User> {}
- Entity层
/**
*
* 实体类, 一张表只对应一个实体
*
* 1.每个类类名和数据库表名一致,
* 2.包含所有字段,
* 3.字段类型跟数据库的字段类型一一对应, 尽量都用包装类型,不要用基础类型,避免查询时出现NPE问题。 字段尽量不要用is开头 例如:is_delete
* 4.每个字段要写清楚注释
*
*
*/
@Data
@TableName("user")
public class User extends BaseEntity {
/**
* 用户名 唯一标识
*/
@TableField("username")
private String username;
/**
* 用户昵称
*/
@TableField("nick_name")
private String nickName;
}
- DTO层
这一层,我建议Request,Response,VO,数据传输对象。request用来接收前端传来的参数,response用来封装返给前端的数据
目录结构大体如下:
dto // 数据传输层
request // 接收前端参数
response // 封装返给前端的参数
transformer // 将request -> entity(po), entity(po) 转 response
vlidate // 校验器,用于控制器校验数据,
五、接口要求
1.统一遵循restful风格
1.1 URL命名原则
1)URL请求采用小写字母,数字,部分特殊符号(非制表符)组成。
2)URL请求中不采用大小写混合的驼峰命名方式,尽量采用全小写单词,如果需要连接多个单词,则采用连接符“_”连接单词
1.2 URL分级
第一级Pattern为模块,比如组织管理/orgz, 网格化:/grid
第二级Pattern为资源分类或者功能请求,优先采用资源分类
1.3 CRUD请求定义规范(RESTful)
如果为资源分类,则按照RESTful的方式定义第三级Pattern,
RESTful规范中,资源必须采用资源的名词复数定义。
1.4 特定请求
1)资源的特定请求
采用在资源下面定义特定的请求pattern,见如下示例
/module/tickets/recently_closed
备注:此情况下需要区分/module/tickets/{id},要避免URL无法区分,通用的配置请求要具备优先适配能力。
2)非特定资源类
请求URL采用如下形式: /module/buy_tickets
————————————————---------------------------
新增:@PostMapping("")
修改:@PutMapping("/{id}")
查询详情:@GetMapping("/{id}")
列表:@GetMapping("")
删除:@DeleteMapping("/{id}")
例如:用户模块
请求类型 | URL | 功能说明 |
GET | /users | 查询用户列表 |
POST | /users | 创建一个用户 |
GET | /users/id | 根据ID查询一个用户 |
PUT | /users/id | 根据ID更新一个用户 |
DELETE | /users/id | 根据id删除一个用户 |