注:参考了《阿里巴巴Java开发手册》 阿里编码规范考试认证:https://edu.aliyun.com/certification/cldt02 一、命名规范

  1. 包名,类名,方法名,变量名 (重要)
    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 前缀,否则部分框架解析会引起序列化错误。
  2. 其他
    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”);
  3. 【参考】各层命名规约:
    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。

二、注释规约

  1. 所有的类都必须添加创建者和创建日期:作者和时间:@author,@date
/**
	 * 渠道数据统计-报表控制器
	 *
	 * @author Xiang Jiangcheng
	 * @date 2020/3/6
	 */
  1. 类、类属性、类方法的注释必须使用 Javadoc 规范,使用/*内容/格式,不得使用// xxx 方式。
  2. 所有的抽象方法(包括接口中的方法)必须要用 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);
  1. 方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/* */注释,注意与代码对齐。
    注: 其实还应该给每个文件加上copyright信息,格式如下
/*
 * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 */

三、异常

  1. 开发中,如果某个方法里面有逻辑可能会产生已知的异常,一定要手动catch,并处理,或者往外抛。具体怎么处理看业务
  2. 有 try 块放到了事务代码中,catch 异常后,如果需要回滚事务,一定要注意手动回滚事务。
  3. 防止 NPE,是程序员的基本修养,注意 NPE 产生的场景:
    1) 数据库的查询结果可能为 null。
    2) 远程调用返回对象时,一律要求进行空指针判断,防止 NPE。
    所以,如果调用者和被调用者,都应该尽量避免NPE。
例如:A去调用B提供的方法,或者接口。 
B定义的方法List<T> getUserList(),返回结果是一个list,如果没有用户信息,那么这个方法是应该返回null呢,还是一个空数组?
所以,A调用B的接口,A自己应该判空,防止NPE。不管B最终返回的是null,还是空数组,都不会报NPE

四、实际开发规约

  1. Controller层
    这一层控制简单的业务逻辑,包括数据校验,不要写太多代码。返回数据类型不能直接是Map,List,应该封装成bean返回,
  2. 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 {}
  1. 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> {}
  1. 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;
   }
  1. 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删除一个用户