java开发编程
提交的代码必须符合阿里巴巴的代码检查工具,代码检查有违反规约不能上测试、生产环境
命名规约
【强制】类名使用 UpperCamelCase 风格,必须遵从驼峰形式,但以下情形例外:DO / BO /DTO / VO / AO
正例:MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion
反例:macroPolo / UserDo / XMLService / TCPUDPDeal / TAPromotion
BO 业务对象,封装对象、复杂对象 ,里面可能包含多个类;
DTO 传输对象,前端调用时传输 ;
VO 表现对象,前端界面展示。
【强制】方法名、参数名、成员变量、局部变量都统一使用lowerCamelCase风格,必须遵从 驼峰形式。
正例: localValue / getHttpMessage() / inputUserId
【强制】常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。
【强制】各种功能类的命名
类型 | 规约 |
---|---|
抽象类 | 名称以Abstract 开头 |
异常类 | 名称以 Exception 结尾 |
测试的类 | 名称以 Test 结尾 |
组件类 | 名称以Component结尾 |
枚举类 | 以Enum 结尾 |
【强制】包名统一使用小写
【强制】禁止中英文混写
【强制】Controller类中的方法,下面提供通用的方法名
方法名 | 解释 |
---|---|
save | 添加 |
edit | 修改 |
delete | 删除 |
list | 列表的json |
【强制】Controller类api路径格式
1)类上使用@RestController注解
2)方法上分别使用@GetMapping,@PostMapping,@DeleteMapping,@PutMapping注解
比如对会员进行增删该查
方法 | 正例 | 反例 |
---|---|---|
增 | @PostMapping("/members") | @PostMapping("/save-member") |
删 | @DeleteMapping("/members/{member_id}") | @DeleteMapping("/delete-member") |
改 | @PutMapping("/members/{member_id}") | @PostMapping("/update-member") |
查 | @GetMapping("/members") | @GetMapping("/get-member") |
3)api组成
业务模块关键字/业务关键字
业务模块关键字
店铺 shop 商品 goods 会员 member 促销 promotion 订单 order 系统 system 楼层 floor
9.【参考】各层命名规约
A)Service/DAO层方法命名规约
1)获取单个对象的方法用get做前缀。
2)获取多个对象的方法用list做前缀。
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。
常亮定义
【强制】long 或者 Long 初始赋值时,使用大写的 L,不能是小写的 l,小写容易跟数字 1 混淆,造成误解。
【推荐】不要使用一个常量类维护所有常量,按常量功能进行归类,分开维护。 说明:大而全的常量类,不利于理解和维护。
正例:缓存相关常量放在类 CacheConsts 下;系统配置相关常量放在类 ConfigConsts 下。
OOP 规约
【强制】所有的覆写方法,必须加@Override 注解。 说明:getObject()与 get0bject()的问题。一个是字母的 O,一个是数字的 0,加@Override可以准确判断是否覆盖成功。另外,如果在抽象类中对方法签名进行修改,其实现类会马上编译报错。
【强制】接口过时或废弃必须加@Deprecated 注解
【强制】Object 的 equals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用equals。 正例:"test".equals(object); 反例:object.equals("test");
【强制】所有的相同类型的包装类(Integer 等)对象之间值的比较,全部使用 equals 方法比较。
控制语句
【强制】在一个 switch 块内,每个 case 要么通过 break/return 等来终止,要么注释说明程序将继续执行到哪一个 case 为止;在一个 switch 块内,都必须包含一个 default 语句并且放在最后,即使它什么代码也没有。
【强制】在 if/else/for/while/do 语句中必须使用大括号。即使只有一行代码,避免采用单行的编码方式:if (condition) statements;
【推荐】表达异常的分支时,少用 if-else 方式,这种方式可以改写成: if (condition) { ... return obj; } // 接着写 else 的业务逻辑代码; 说明:如果非得使用 if()...else if()...else...方式表达逻辑,请勿超过 3 层。
注释规约
【强制】类、类属性、类方法的注释必须使用 Javadoc 规范,使用
/** 内容 */
格式,不得使用// xxx
方式。 说明:在 IDE 编辑窗口中,Javadoc 方式会提示相关注释,生成 Javadoc 可以正确输出相应注释;在 IDE 中,工程调用方法时,不进入方法即可悬浮提示方法、参数、返回值的意义,提高阅读效率。【强制】所有的抽象方法(包括接口中的方法)必须要用 Javadoc 注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。 说明:对子类的实现要求,或者调用注意事项,请一并说明。
【强制】所有的类都必须添加创建者、创建日期、版本。
版本号(外部开发使用vfX.Y.Z
)说明,vf:表示外部人员
X主版本号:全盘重构时增加;重大功能或方向改变时增加;大范围不兼容之前的接口时增加。
Y次版本号:增加新的业务功能或大的修改,可以按照期数增加。
Z修订号:增加新的接口、BUG修复或小的优化时增加;在接口不变的情况下,增加接口的非必填属性时增加;增强和扩展接口功能时增加。
示例:外服开发人员,第三期的版本号为:vf1.3.0,若有小问题修复则vf1.3.1
【强制】方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用
/* */
注释,注意与代码对齐。【强制】所有的枚举类型字段必须要有注释,说明每个数据项的用途。
【推荐】代码修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑等的修改。 说明:代码与注释更新不同步, 就失去了注释的意义。
【强制】TODO 需求注明添加TODO的人员
异常处理
【强制】Java 类库中定义的一类 RuntimeException 可以通过预先检查进行规避,而不应该通过 catch 来处理,比如:IndexOutOfBoundsException,NullPointerException 等等。 说明:无法通过预检查的异常除外,如在解析一个外部传来的字符串形式数字时,通过 catch NumberFormatException 来实现。 正例:if (obj != null) {...} 反例:try { obj.method() } catch (NullPointerException e) {...}
【强制】异常不要用来做流程控制,条件控制,因为异常的处理效率比条件分支低。
【强制】对大段代码进行 try-catch,这是不负责任的表现。catch 时请分清稳定代码和非稳定代码,稳定代码指的是无论如何不会出错的代码。对于非稳定代码的 catch 尽可能进行区分异常类型,再做对应的异常处理。
【强制】捕获异常是为了处理它,不要捕获了却什么都不处理而抛弃之,如果不想处理它,请将该异常抛给它的调用者。最外层的业务使用者,必须处理异常,将其转化为用户可以理解的内容。
【强制】有 try 块放到了事务代码中,catch 异常后,如果需要回滚事务,一定要注意手动回滚事务。
【强制】finally 块必须对资源对象、流对象进行关闭,有异常也要做 try-catch。 说明:如果 JDK7 及以上,可以使用 try-with-resources 方式。
【强制】不能在 finally 块中使用 return,finally 块中的 return 返回后方法结束执行,不会再执行 try 块中的 return 语句。
【推荐】方法的返回值可以为 null,不强制返回空集合,或者空对象等,必须添加注释充分说明什么情况下会返回 null 值。调用方需要进行 null 判断防止 NPE 问题。 说明:本手册明确防止 NPE 是调用者的责任。即使被调用方法返回空集合或者空对象,对调用者来说,也并非高枕无忧,必须考虑到远程调用失败、序列化失败、运行时异常等场景返回null 的情况。
【推荐】防止 NPE,是程序员的基本修养,注意 NPE 产生的场景: 1)返回类型为基本数据类型,return 包装数据类型的对象时,自动拆箱有可能产生 NPE。 反例:public int f() { return Integer 对象}, 如果为 null,自动解箱抛 NPE。 2) 数据库的查询结果可能为 null。 3) 集合里的元素即使 isNotEmpty,取出的数据元素也可能为 null。 4) 远程调用返回对象时,一律要求进行空指针判断,防止 NPE。 5) 对于 Session 中获取的数据,建议 NPE 检查,避免空指针。 6) 级联调用 obj.getA().getB().getC();一连串调用,易产生 NPE。 正例:使用 JDK8 的 Optional 类来防止 NPE 问题
【推荐】定义时区分 unchecked / checked 异常,避免直接抛出 new RuntimeException(),更不允许抛出 Exception 或者 Throwable,应使用有业务含义的自定义异常。推荐业界已定义过的自定义异常,如:DAOException / ServiceException 等。
【参考】在代码中使用“抛异常”还是“返回错误码”,对于公司外的 http/api 开放接口必须使用“错误码”;而应用内部推荐异常抛出;跨应用间 RPC 调用优先考虑使用 Result 方式,封装 isSuccess()方法、“错误码”、“错误简短信息”。 说明:关于 RPC 方法返回方式使用 Result 方式的理由: 1)使用抛异常返回方式,调用方如果没有捕获到就会产生运行时错误。 2)如果不加栈信息,只是 new 自定义异常,加入自己的理解的 error message,对于调用端解决问题的帮助不会太多。如果加了栈信息,在频繁调用出错的情况下,数据序列化和传输 的性能损耗也是问题。
【参考】避免出现重复的代码(Don’t Repeat Yourself),即 DRY 原则。 说明:随意复制和粘贴代码,必然会导致代码的重复,在以后需要修改时,需要修改所有的副本,容易遗漏。必要时抽取共性方法,或者抽象公共类,甚至是组件化。 正例:一个类中有多个 public 方法,都需要进行数行相同的参数校验操作,这个时候请抽取: private boolean checkParam(DTO dto) {...}
数据库数据处理
所有的更新和保存操作都需要更新数据库字段updater和update_time,所有保存都需要写入creater和create_time