摘要
统一异常处理、规范日志打印和国际化、参数定义和参数校验、规范方法返回值、规范接口定义、明确Conroller、Service层负责功能
为什么要规范开发风格?
复盘开发加班原因,主要有两点:
- 反复定位问题、修改并测试代码
- 需求变更
怎样减少开发交付时间?
- 尽量完备的测试用例测试后交付
- 规范编码风格,减少因需求变更和修改bug带来的工作量
规范编码风格
1. 明确Controller、Service层负责功能
(1)Controller层负责功能
- Controller层只做参数转换
- 不允许出现和业务无关的参数,例如response、request、local类型参数
- Controller和Service层之间不允许使用json,map之类格式交互数据,而是使用自定义Bean
- 不允许打印日志,捕获异常,日志和异常应该在service层或AOP处理。
- 统一返回格式,方便AOP统一处理异常(2)service层负责功能
- 参数校验、权限校验、日志打印
- 核心业务逻辑
2.接口定义规范
规范接口入参和返回格式,有利于前端和其他服务调用时,代码复用
- 不要出现和业务无关的入参
- 统一定义接口返回格式ResultBean,且通过返回格式中的code判断请求状态
接口定义示例和ResultBean示例
public ResultBean getInfoById(@PathParam("id") String id) { return new ResultBean(assetInfoQueryService.getAssetInfoByAssetId(new AssetIdQueryParam(id))); } public class ResultBean implements Serializable { private static final long serialVersionUID = 1L; public static final int SERVERERROR = 001; public static final int PARAMSERROR = 002; public static final int DELETEERROR = 002; public static final int SUCCESS = 0; public static final String PARAMSERRORMSG = "参数非法"; public static final String SERVERERRORMSG = "服务异常"; private String message;//失败填错误信息,成功填null private int code = SUCCESS;//成功填0,失败填错误码 private Object result;//无数据填null public ResultBean() { super(); } public ResultBean(Object result) { super(); this.result = result; } /** * 无数据时result填null,异常情况存在 */ public ResultBean(Throwable e) { super(); this.message = e.toString(); this.code = SERVERERROR; this.result = null; } }
3.日志记录要点
记录的日志可以找到虚机节点信息;知晓用户关键操作;明确关键业务逻辑参数
- 修改、增加数据时,打印关键参数
- 核心业务中条件分支参数值
- 业务数据量和耗时
4.异常统一处理
异常统一使用AOP处理
- 不要捕获运行时异常(除IO相关),自定义异常继承RuntimeException
- 不要判空,会掩盖业务数据错误(除业务中存在空数据情况)
- web请求异常不允许捕获,全部向上抛出,交给AOP统一处理。后台线程、队列异常,需要捕获处理,且需要打印出日志,甚至邮件通知
@Component @Aspect public class AssetInfoQueryControllerAOP { /** * pointcut所有throw的异常,都会在下面Advice中统一处理。并返回result */ @Around(value = "execution(* com.zte.zj.es_practice.zj.AssetInfoQueryController.*(..))") public Object catchException(ProceedingJoinPoint joinPoint) { ResultBean result; try { result = (ResultBean) joinPoint.proceed(); } catch (Throwable e) { result = handlerException(joinPoint, e); } return result; } }
5.方法编码规范
- 明晰的方法和参数命名,降低代码阅读难度
- 方法按功能(需求)拆分解耦,降低后续因需求变更带来的工作量
public void updateUserNickName(long userId, String nickname){ //更新代码 }
参考: