java开发规范

star2017 1年前 ⋅ 520 阅读

俗话说世界之大什么人都有,对于程序员也是一样,如果没有一个规范来制约,那么项目可能就会出现很多风格。

项目分层

image.png

应用一般包括以下几个逻辑层(xxx为应用名):

  • xxx-portal:请求处理层,负责对外提供 http 和 rpc 接口,也可以把RPC单独抽出来作为一层。
  • xxx-business:业务逻辑层,在这一层做的事情除了组装原子服务层的接口以外,还可以调用外部依赖的 rpc 服务,或者消费 MQ 消息。
  • xxx-service:原子服务层,对dao层的方法进行组装。
  • xxx-dao:数据访问层,提供增删改查在内的原子服务。
  • xxx-sdk(可选):RPC 接口对外提供的 API 包。

项目之前的依赖约定:

  • portal-sdk 对内只会被对应的 portal 层依赖
  • business 只会被对应的 portal 层依赖
  • service 可以被对应的 business 层依赖,也可以被对应的 portal/rpc 层依赖
  • dao 只会被对应的 service 层依赖

以上涉及的依赖访问全部是基于接口依赖

命名规范

域名反过来.业务线.子业务线.产品名.逻辑层名

com.chaiguanxin.baseservice.uc.auth.business

POJO约定

  • portal 传入对象统一以DTO结尾,传出对象统一以VO 结尾。
  • rpc 传入或者传出的对象除了简单对象以外,统一定义为 DTO 对象,命名统一以 RequestDTO 或 ResponseDTO 结尾。

命名约定

  • Service/DAO 层方法命名规范:
    • 获取单个对象的方法用 get 作为前缀
    • 获取多个对象的方法使用 list 作为前缀
    • 获取统计值的方法使用 count 作为前缀
    • 插入的方法用 save 作为前缀
    • 删除的方法用 remove 作为前缀
    • 修改的方法用 update 作为前缀
  • 领域模型命名规范:
    • 数据对象:xxxEntity,xxx为数据表名
    • 数据传输对象:xxxDTO,xxx 为业务领域相关的名称
    • 展示对象:xxxVO,xxx一般为网页名称

命名风格

  • 命名不能使用下划线或者美元符号开头或者结尾
  • 代码中的命名严禁使用拼音与英文混合的方式
  • 类名使用 UpperCamelCase 风格,但 DO、BO、DTO、VO 等情形除外
  • 方法名、参数名、成员变量、局部变量都统一使用 lowCamelCase 风格
  • 常量命名全部大写,单词间用下划线隔开,力求语意表达完整清楚,不要嫌名字长
  • 抽象类命名使用 Abstract 或 Base 开头,异常类命名使用 Exception 结尾,测试类命名以它要测试的类名开始,以 Test 结尾
  • 包名统一使用小写,点分隔符之间有且只有一个自然语意的英语单词。包名统一使用单数形式,类名允许使用复数形式
  • 尽量避免会引起歧义的缩写
  • 如果模块、接口、类等使用了设计模式,应在命名时体现出具体模式
    public class ConsumerFacadeFactory
    public class AccountFacadeProxy 
    
  • 对于 Service 和 DAO 类,基于 SOA 的理念,暴露出来的服务一定是接口,内部的实现类用 Impl 后缀与接口区别
    CacheServiceImpl 实现 CacheService 接口

常量定义

  • long 或者 Long 初始赋值时,使用大写的 L,不能用小写的 l,避免误读
  • 如果变量值仅在一个范围内变化,则用 enum 类型来定义

代码风格

  • 注释的双斜线与注释内容之间有且只有一个空格
  • 关于换行
    • 方法调用的点符号与下文一起换行
    @Override
    public boolean xxx(String zz) {
      return xx.create(zzz, aaa)
              .aaa(aaa)
              .build()
              .aaa(token)
              .bbb()
              .ccc();
    } 
    
    • 方法调用中的多个参数需要换行时,在逗号后进行
    String.format("%s?aaa=%s&bbb=%s&ccc=%s",
                  zzzz,
                  aaa,
                  bbb,
                  ccc);
    

OOP约定

  • 所有的覆写方法,必须加 @Override 注解
  • Object 的 equals 方法容易抛出空指针异常,应使用常量或确定有值的对象来调用 equals
  • 当序列化类新增属性时,不要修改 serialVersionUID 字段,避免反序列化失败
  • 构造方法里面禁止加入任何业务逻辑,如果有初始化逻辑,请放入 init 方法中

集合约定

  • PECS原则:频繁往外读取内容的,适用 <? extends T>;频繁往里插入的,适用 <? supper T>
  • 不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素需使用 Iterator 方式。

并发约定

  • 在并发修改同一记录时,为避免更新丢失,需要加锁。要么在应用层加锁,要么在缓存层加锁,要么在数据库使用乐观锁,使用 version 作为更新依据。如果每次访问冲突概率小于20%,推荐使用乐观锁,否则使用悲观锁。乐观锁的重试次数不得小于3次。
  • 超过 3 层的 if-else 逻辑判断代码可以使用卫语句(短路的写法)、策略模式、状态模式等来实现。

注释规范

  • 类、类属性、类方法的注释必须使用 Javadoc 规范,使用 /** 内容 */ 的格式,不得使用 // 方式
  • 所有类的注释中都必须添加创建者和创建日期
  • 方法内部的单行注释,在被注释的语句上方另起一行,使用 // 注释
  • 在修改代码的同时,要对注释进行相应的修改

日志规范

  • 日志输出语句中尽量使用占位符的形式,避免使用字符串拼接的形式
  • 日志打印统一使用 @Slf4j 注解

安全规范

  • 为了防止 SQL 注入,禁止字符串拼接 SQL 访问数据库

ORM映射

  • 在表查询中,禁止使用 * 作为查询的字段列表,需要哪些字段必须明确写明
  • mybatis 中的 xml 文件中参数使用 #{} 的写法,尽量避免使用 ${} 的写法
  • 更新记录时,必须同时更新记录的最后修改时间字段
  • mybatis 中的 xml 文件中的 SQL 语句关键字大写,其他都小写

数据库规范

  • 表名、字段名必须使用小写字母,禁止出现数字开头,禁止两个下划线中间出现数字。
  • 表名不使用复数名词
  • 主键索引名为 pk_字段名,唯一索引名为 uk_字段名,普通索引名为 idx_字段名
  • 每个表必备的三个字段:id、create_time、update_time
  • 表名推荐使用以下规则 "所属系统名_业务名_表的作用"
  • sql 语句中禁止使用左模糊或者全模糊查询
  • 建组合索引的时候区分度最高的放在最左边
  • 不得使用外键与级联,一切外键概念必须在应用层解决
  • in 操作要控制在 1000 个以内

代码仓库规范

  • 私服仓库中的jar包的三围定义规则
    • groupId 格式: com.chaiguanxin.业务线.子业务线
    • artifactId 格式:产品线名-模块名
    • version 格式,起始版本号必须是 1.0.0 ,正式版本号不允许覆盖升级:
    • 主版本号:产品方向改变,或者大规模 API 不兼容,或者架构不兼容升级
    • 次版本号:每月迭代自增加一
    • 修订号:如果月迭代发现线上 bug,修复上线的版本修订号自增加一
  • 所有 pom 文件中的依赖声明放在 语句块中,所有版本放在 语句块中
  • 仓库中 jar 包的提供者应该遵循精简可控原则,如果所提供的 jar 包依赖其它 jar 包,尽量是 provided 引入,让 jar 包的使用者依赖具体的版本号

单元测试规范

以下几个关键环节必须被单元测试覆盖:

  • dao 层暴露给 service 层的每个方法
  • service 层暴露给 business 或 portal 层的每个方法
  • business 层暴露给 portal 层的每个方法
  • portal 层暴露给外部调用的每个接口 ( 包括 HTTP 和 Dubbo 接口 )

各层单元测试的编写规范

  • dao 层单元测试类需要继承 BaseDaoTest 类,测试类以被测试的类名开头、以 Test 结尾
  • service、business 层单元测试类需要继承 BaseServiceTest 类,测试类以 ServiceTest、BusinessTest 结尾
  • portal 层 HTTP 服务的单元测试类需要继承 BaseHttpTest 类,测试类以 ControllerTest 结尾
  • portal 层 Dubbo 服务的单元测试类以 FacadeTest 结尾
  • 单元测试中使用的断言统一使用 org.junit.Assert 类下面的静态方法
  • 单元测试的结果必须用 assert 进行断言判断,禁止使用控制台输出的方式通过肉眼识别测试结果
本文为博主原创文章,未经博主允许不得转载。
更多内容请访问:IT源点

相关文章推荐

全部评论: 0

    我有话说: