我的代码开发规范

从方法命名、框架领域命名规范、注释规范、消息队列规范说

Posted by Zheng Yang on August 11, 2024

后端代码规范

方法命名

  1. 获取单个对象的方法用 get 作前缀

​ 例如:查询单个用户 getStudent,按照 ID 查询单个用户 getStudentById。

  1. 获取多个对象的方法用 list 作前缀

​ 例如:按照 IDS 查询多个用户,listStudentByIds。

  1. 获取统计值的方法用 count 作前缀

​ 例如:统计全量用户,countUser。

  1. 插入的方法用 save 作前缀

​ 例如:新增用户,saveUser。

  1. 删除的方法用 remove 作前缀

​ 例如:删除用户,removeUser。

  1. 修改的方法用 update 作前缀

​ 例如:修改用户,updateUser。

领域模型命名规约

1. 数据对象

xxxDO,xxx 即为数据表名。 比如学生数据对象:StudentDO。

2. 数据传输对象

xxxDTO,xxx 为业务领域相关的名称。

这里又分为两种,分别是请求入参和请求出参,以学生新增接口为例:

  • 入参:StudentSaveReqDTO
  • 出参:StudentSaveRespDTO

如果是分页查询学生接口,示例如下:

  • 入参:StudentPageQueryReqDTO
  • 出参:StudentPageQueryRespDTO

3. 项目配置类

xxxConfiguration,xxx 为配置类型。 比如数据库持久层配置类:DataBaseConfiguration。

4. 常量类

xxxConstant,xxx 为常量领域。比如项目中公共 Redis 配置:RedisCommonConstant。

5. 上下文

xxxContext,xxx 为上下文类型。 比如用户存储上下文:UserContext。

6. 枚举类

xxxEnum,xxx 表示什么类型的枚举。比如用户优惠券状态枚举:UserCouponStatusEnum。

7. 注意事项

POJO 是 DO/DTO/BO/VO 的统称,禁止命名成 xxxPOJO。

注释规范

1. 注释说明意图即可,无需补充冗余字段

【强制】Class、Interface、Enum、@interface 等文件类型,类上注释仅需说明类的意图即可。 不需要补充时间和创建人,因为 往往开发代码的不止是一个人,容易造成信息干扰。 需要的话,查看提交记录即可。

/**
 * 适配第三方框架的线程池
 */
public interface ThreadPoolAdapter {

}

2. 方法上需要添加注释

【强制】方法上需添加注释,并说明清楚方法的意图(接口实现类无需注释); 必要时描述 @param @return。

/**
 * 适配第三方框架的线程池
 */
public interface ThreadPoolAdapter {

    /**
     * 修改框架线程池的核心参数
     *
     * @param threadPoolBaseInfo  修改线程池的基础参数
     * @return  线程池核心参数修改结果
     */
    boolean updateThreadPool(ThreadPoolBaseInfo threadPoolBaseInfo);
}

如果方法为内部引用方法,并且方法名称见名知意,无需方法注释。

3. 方法块内部注释规范

【强制】方法内部的注释,应该新起一行,而不是跟在代码后面。

正例
// 刷新动态线程池参数
refreshDynamicPool(parameter, executor);

反例
refreshDynamicPool(parameter, executor); // 刷新动态线程池参数

4. 方法命名说明方法本身意图

【强制】私有方法尽量通过方法命名说明方法语义。

消息队列使用规范

1 消息发送

1)【强制】消息生产者创建时,必须指定生产者组。

2)【强制】一个系统对应一个 Topic,系统下的不同业务根据 Tag 区分,参考申请规范-消费应用 Tag。

3)【强制】发送消息时,需设置 KEYS。 KEYS 建议定义为业务唯一标识,比如订单 ID。

4)【强制】发送消息不管发送成功或失败,需打印 KEYS、Payload、执行时间以及 SendResult

5)【强制】发送消息时,需设置超时时间,避免应用被拖垮; 建议超时时间设置为 2000ms 内。

6)【建议】针对可靠性较高的消息,发送失败后可以存储到 DB,开启定时任务扫描,并重新投递。

2 消息消费

1)【强制】消费端创建时,必须指定消费者组。

2)【强制】消费端需要保证数据幂等。

3)【强制】消费消息不管成功或失败,需打印 KEYS、MsgId、执行时间以及 Message。

4)【强制】不同的应用集群应使用不同的消费者组,如果不同的应用集群需要订阅同一消费者组,需保证 Topic Tag 订阅关系一致。

1663550134348-88d58115-092f-49cb-85d6-cf72280be781-1.webp 5)【强制】打印消息消费日志。

log.info("Execute result: {}, Keys: {}, Dispatch time: {} ms, Execute time: {} ms, Message: {}", ...);

6)【建议】消费时尽量不设置重试,大部分情况下,执行失败的消息重试后会再次失败,反而会影响消费进度。 开发者应该针对特定场景在代码中设置重试逻辑。

7)【建议】消费者并发消费数量默认为 1,即串行化,应该基于不同系统场景来设置并发数,同时要考虑消费过程中其它组件的压力。

  • 系统 CPU 任务少: *CPU 核数 / (1 - 阻塞系数 0.8)*
  • 系统 CPU 任务较多,建议 即可。CPU 核数 + 1