Java 编码规范

文章目录
  1. 1. 数据库
  2. 2. DAO和service层
  3. 3. REST url设计
  4. 4. PO,VO,DTO
  5. 5. 工具类和常量类
  6. 6. 单路单例配置
  7. 7. 方法
  8. 8. 格式公约
  9. 9. 其他

数据库

  • 在数据库中涉及到命名时一律用全小写,单词之间用下划线分隔。
  • 表明命名不要使用复数形式,例如user表不要起名为base_t_users。
  • 命名可以借鉴使用以下格式:模块标识、对象类型、对象标识,以下划线区分。
    例如 base_t_user,base_v_user。
  • 用 t 表达表,用 v 表达视图,特殊地, tj 表明这是一张关联表, j 代表join, ti 表明这是一张接口表, i 代表interface
  • 所有的表都默认添加三个字段id,create_time 与 update_time。
  • 主键统一命名为id,不要使用其他诸如【表名+id】的形式。例如 base_t_user 的主键不要使用 base_t_user_id。
  • 所有布尔类型的字段,统一用 is_ 开头。例如 is_deleted 。布尔类型字段用于只有两个待选值的场景。
  • 所有枚举类型的字段,统一用 enum_ 开头。例如 enum_state 。枚举类型字段用于多于两个待选值的场景。
  • 所有json类型的字段,统一用 _json 结尾。因为在程序中将表现为string类型,需要在名称上显示出来该数据本身是json格式。
  • 所有时间戳类型的字段,统一用 _time 结尾。
  • 所有日期类型的字段,统一用 _date 结尾。
  • 所有表达“总数”的字段,统一用 _total 结尾。
  • 所有外键关联的字段,统一用 _id 结尾。
  • 所有varchar类型字段,根据实际需要给定范围。
  • 能给默认值的字段,一定要给默认值。比如布尔类型,创建日期等。
  • 原则上非空或者不能重复的字段,要配置好相应约束。

PS:主键有效原则
操作数据时,比如更新,删除等,尽量只提供根据主键操作的接口。
即一般情况下,如果不知道某行数据的主键的话,将不能对其进行操作。


DAO和service层

(1)DAO层

  • DAO层方法,如果参数达到四个以上,就封装成dto传入,反之则使用 @Param 注解,即不允许出现五个参数。
  • 参数应该体现在方法名称上,使用 By…And…And… 的形式。
    前后顺序最好与参数列表中的顺序一致。这种命名可能导致名字很长,但是更加语义化。
  • update,insert,delete方法的返回值使用int,不要用void,哪怕int暂时用不着。
  • 方法前缀:
    • 返回一条结果: selectOne
    • 返回多条结果: selectList
    • 返回全部结果: selectAll
    • 返回count: count
    • 新增: insert
    • 修改: update
    • 假删除: delete

在DAO层中保持以上命名规则,在命名时,更多地使用SQL语言中的动词,比如select、insert、update等。以清楚地表明该方法直接操作了数据库。

(2)service层
service层中避免使用以上的方法开头,也避免使用SQL语言中的关键字,应该倾向于体现业务逻辑。如:

  • 返回一条结果: queryOne
  • 返回多条结果: queryList
  • 返回全部结果: queryAll
  • 返回count: count
  • 新增: save
  • 修改: modify
  • 假删除: remove
  • 远端拉取调用数据,比如调用api返回等:使用 pull 开头,表明从远端“拉取”数据。

REST url设计

在保证语义化的基础上,尽量简化单词,隐藏原有意义,避免暴露逻辑。

假如模块自身的业务接口统一以 /m 开头
公用的API数据接口统一以 /a 开头

后续逐级细分功能,如
/m/cross/book
表明是一个自身业务模块,是模块当中的图书漂流,是图书漂流中的图书管理功能。

但以上url应该继续修正为: /m/c/b 或者 /m/b_c/b 这种形式,这样能避免用户从url中猜出业务逻辑。

REST风格要求在url上不体现操作动作,而全部使用名词来指定资源,在请求中指定操作动作,但实际应用中达不到这样的标准。所以建议统一用CRUD来代表增删改查四种操作,对于开发人员有足够的语义,对于用户也能起到足够的混淆。比如这样:
/m/c/b/r/{bookId}
即代表根据bookId读取一条记录。
同样是查询,可能根据不同需求有多种实现,这时可以用数字划分,比如:
/m/c/b/r/1/{groupId}
即根据套系查询书籍。

尽量避免在url上提供参数,url上能提供的参数只应该有id,且只能有一个,即通过get请求,并将参数拼接在url上返回的场景,只能是单主键查询。其他的操作统一使用post请求。这样可以保持url的短小简洁。


PO,VO,DTO

  • PO用于映射数据表,与数据库表对象严格一一对应,属性与表字段严格一一对应。
  • VO封装查询结果集,用于展示,根据查询复杂程度,内部可能有集合等复杂类型成员变量。VO本身不严格对应某张表,VO的字段也不严格映射表的字段。VO中禁止出现查询条件。
  • DTO用于封装查询参数,此类对象更多地服务于程序本身,可能封装一些跟数据库无关但是跟业务相关的参数,根据查询场景不同,也会封装分页参数。DTO中禁止出现结果集。

工具类和常量类

(1)工具类
工具类分两种,一种是以 tool 结尾,这种工具类更接近业务逻辑,依赖除JDK以外的包。
一种是以 util 结尾,这种工具类更接近底层算法,除了JDK没有其他任何依赖。
tool和util工具类类名统一加s或者不加s,比如不要同时出现 AUtil 与 BUtils。

(2)常量类
常量类要将构造方法私有化,并在类名上加 final 前缀。内部的常量字段全部加 public static final 前缀。


单路单例配置

配置功能应该有且仅有一种途径可以访问到。同样功能的配置只能有一处。
比如某些配置需要有前台页面展示,让管理员可以修改,那么这些配置放在数据库中,绝对禁止同时放在配置文件中。
而如果某些配置放在properties等类似配置文件中,那么绝对禁止通过某个页面访问修改。
这样的原则避免二义性,使得配置有且仅有一个,也避免多处配置同步的问题。


方法

  • 方法返回如果为集合类型,比如 List,则该集合不允许为null,无值的时候默认一个空的集合即可。
  • 一般情况下,方法应该尽量有一个返回值而不使用void。比如DAO层的update,insert,delete方法返回值建议使用int。
  • 方法使用动词开头。但是要尽量避免使用 get 和 set 开头,因为这样容易与属性访问器混淆。
  • 一个方法尽可能只做一件事情,如果命名时候出现”做某件事and某件事”,就说明方法需要拆分。
  • 方法尽量不超过50行,否则要尝试重构。
  • 原则上,if后面需要接else。
  • 方法在返回值时,能简写就简写。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 反例
    public int test() {
    int a = 1+1;
    return a;
    }

    # 正例
    public int test() {
    return 1+1;
    }

格式公约

  1. 【强制】大括号的使用约定。如果是大括号内为空,则简洁地写成{}即可,不需要换行 ; 如果
    是非空代码块则:
    1 ) 左大括号前不换行。
    2 ) 左大括号后换行。
    3 ) 右大括号前换行。
    4 ) 右大括号后还有 else 等代码则不换行 ; 表示终止右大括号后必须换行。
  2. 【强制】 左括号和后一个字符之间不出现空格 ; 同样,右括号和前一个字符之间也不出现空格。详见第 5 条下方正例提示。

  3. 【强制】 if / for / while / switch / do 等保留字与左右括号之间都必须加空格。

  4. 【强制】任何运算符左右必须加一个空格。
    说明:运算符包括赋值运算符=、逻辑运算符&&、加减乘除符号、三目运行符等。

  5. 【强制】缩进采用 4 个空格,禁止使用 tab 字符。
    说明:如果使用 tab 缩进,必须设置 1 个 tab 为 4 个空格。
    IDEA 设置 tab 为 4 个空格时,请勿勾选 Use tab character ;
    而在 eclipse 中,必须勾选 insert spaces for tabs 。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # 正例:  ( 涉及 1-5 点 )
    public static void main(String[] args) {
    // 缩进 4 个空格
    String say = "hello";
    // 运算符的左右必须有一个空格
    int flag = 0;
    // 关键词 if 与括号之间必须有一个空格,括号内的 f 与左括号,0 与右括号不需要空格
    if (flag == 0) {
    System.out.println(say);
    }
    // 左大括号前加空格且不换行;左大括号后换行
    if (flag == 1) {
    System.out.println("world");
    // 右大括号前换行,右大括号后有 else,不用换行
    } else {
    System.out.println("ok");
    // 在右大括号后直接结束,则必须换行
    }
    }
  6. 【强制】单行字符数限制不超过 120 个,超出需要换行,换行时遵循如下原则:
    1) 第二行相对第一行缩进 4 个空格,从第三行开始,不再继续缩进,参考示例。
    2 ) 运算符与下文一起换行。
    3 ) 方法调用的点符号与下文一起换行。
    4 ) 在多个参数超长,逗号后进行换行。
    5 ) 在括号前不要换行,见反例。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # 正例:
    StringBuffer sb = new StringBuffer();
    //超过 120 个字符的情况下,换行缩进 4 个空格,并且方法前的点符号一起换行
    sb.append("zi").append("xin")...
    .append("huang")...
    .append("huang")...
    .append("huang");

    # 反例:
    StringBuffer sb = new StringBuffer();
    //超过 120 个字符的情况下,不要在括号前换行
    sb.append("zi").append("xin")...append
    ("huang");
    //参数很多的方法调用可能超过 120 个字符,不要在逗号前换行
    method(args1, args2, args3, ...
    , argsX);
  7. 【强制】方法参数在定义和传入时,多个参数逗号后边必须加空格。
    正例:下例中实参的” a “,后边必须要有一个空格。
    method(“a”, “b”, “c”);

  8. 【强制】 IDE 的 text file encoding 设置为 UTF -8 ; IDE 中文件的换行符使用 Unix 格式,
    不要使用 windows 格式。

  9. 【推荐】没有必要增加若干空格来使某一行的字符与上一行的相应字符对齐。
    正例:
    int a = 3;
    long b = 4L;
    float c = 5F;
    StringBuffer sb = new StringBuffer();
    说明:增加 sb 这个变量,如果需要对齐,则给 a 、 b 、 c 都要增加几个空格,在变量比较多的情况下,是一种累赘的事情。

  10. 【推荐】方法体内的执行语句组、变量的定义语句组、不同的业务逻辑之间或者不同的语义之间插入一个空行。相同业务逻辑和语义之间不需要插入空行。
    说明:没有必要插入多行空格进行隔开


其他

看不懂的命名
方法参数太多或者方法太长
不写注释,或写没价值的注释
乱排版,不对齐
废代码
重复代码
各种嵌套
等等。。。

最后,代码虽然是给机器运行的,但最终还是给人看的。。。