Java程序员快速提高代码质量建议
1、概述
相同的业务需求不同层级的程序员实现方式不一样,经验稍微欠缺一点的新手程序员,可能单纯的实现功能,经验丰富的程序员,开发的代码可能会具有很好的扩展性、易读性、健壮性。相信很多小伙伴在工作团队中,有时候会一起code review,互相review代码,其实review代码时大家保持开放包容心态,是一种团队进度的方式。
今天分享的内容主要帮助大家从代码规范的角度,梳理出快速提升代码质量的建议,学完之后可以帮助大家在团队code review时,提供建议,帮大家写出高质量代码。
2、什么样的代码是高质量代码
如何评价一段代码的好与坏,其实是有一定主观性的,不同人有不同的标准和看法,但是总的概括下来优秀的代码一般具有如下特点:
3、如何提高代码质量
这里主要代码规范角度,小伙伴们可以快速理解掌握,并快速使用。
3.1 代码命名
项目名、模块名、包名、类名、接口名、变量名、参数名等,都会涉及命名,良好的代码命名是程序员的基本素养,对代码可读性非常重要。
- 命名原则
1、Java采用驼峰命名,代码命名要使用通俗易懂的词汇,不要采用生僻单词;
2、团队内部或者项目中风格要统一,例如查询类方法,要么都使用findByXXX方式,或者queryByXXX、getByXXX等,不要几种混用,风格保持一致;
3、命名长度:个人建议有时候为了易于理解,可以将命名适当长一些,例如:如下方法,一看就知道是上传照片到阿里云服务器,
public void uploadPhotoImageToAliyun(String userPhotoImageUri){}
可以利用上下文语义简化变量命名长度,如下用户实体类变量命名可以简化,更简洁
public class User {
private String userName;
private String userPassword;
private String userGender;
}
public class User {
private String name;
private String password;
private String gender;
}
4、抽象类通常带有Abstract前缀,接口命名和实现类命名,通常类似这样RoleService,实现类跟一个Impl,如RoleServiceImpl
- 注释
1、良好的代码注释对于可读性很重要,虽然有小伙伴可能会觉得好的命名可以替代注释;
2、个人觉得注释很重要,注释可以起到代码分隔作用,代码块总结作用,文档作用;
3、部分程序设计核心关键点,可以通过注释帮助其他研发人员理解;
4、注释是否越多越好呢,然而并不是这样,太多注释反而让人迷惑,增加维护成本,代码变动之后也需要对注释进行修改。
3.2 代码风格
良好的代码风格,可以提升代码可读性,主要梳理以下几点:
3.3 实用代码技巧
- 将代码分隔成多个单元
代码逻辑太长不易阅读,将代码分隔成多个小的方法单元,更好理解和复用,如下所示,用户注册接口,包含账号、手机号校验及用户保存操作
public Long registerUser(String Account, String mobile, String password){
// 校验账号是否重复
if(StringUtils.isNotBlank(Account)){
User user = userService.getUserByName(Account);
AssertUtils.isNull(user, "用户账号已存在,不能重复");
}
// 校验手机号是否重复
if(StringUtils.isNotBlank(mobile)){
User user = userService.getUserByMobile(mobile);
AssertUtils.isNull(user, "手机号已存在,不能重复");
}
// 保存用户到DB
return userService.insert(Account, mobile, password);
}
重构之后的代码如下:
public Long registerUser(String Account, String mobile, String password){
// 校验账号是否重复
checkAccountIsExists(Account);
// 校验手机号是否重复
checkMobileIsExists(mobile);
// 保存用户到DB
return userService.insert(Account, mobile, password);
}
private void checkAccountIsExists(String Account){
if(StringUtils.isNotBlank(Account)){
User user = userService.getUserByName(Account);
AssertUtils.isNull(user, "用户账号已存在,不能重复");
}
}
private void checkMobileIsExists(String mobile){
if(StringUtils.isNotBlank(mobile)){
User user = userService.getUserByMobile(mobile);
AssertUtils.isNull(user, "手机号已存在,不能重复");
}
}
- 避免方法太多参数
方法太多参数影响代码可读性,当方法参数太多时可以采取将方法抽取为几个私有方法,如下所示:
public User getUser(String username, String telephone, String email);
// 拆分成多个函数
public User getUserByUsername(String username);
public User getUserByTelephone(String telephone);
public User getUserByEmail(String email);
也可以将参数封装为对象,通过抽取为对象对于C端项目还能更好兼容,如果是对外暴露的接口,可以避免新老接口兼容问题
public User getUser(String username, String telephone, String email);
// 重构后将方法入参封装为对象
public class SearchUserRequest{
private String username;
private String telephone;
private String email;
}
public User getUser(SearchUserRequest searchUserReq重构后将方法入参封装为对象
- 不要使用参数null及boolean来判断
使用参数非空和为空作为代码的if、else分支,以及boolean参数作为代码分支,这些都不建议,如果可以尽量拆分为多个细小的私有方法;当然也不是绝对的,实际情况具体分析; - ** 方法设计遵守单一职责**
方法设计不要追求大而全,尽量做到职责单一,粒度细,更易理解和复用,如下所示:
public boolean checkUserIfExisting(String telephone, String username, String email) {
if (!StringUtils.isBlank(telephone)) {
User user = userRepo.selectUserByTelephone(telephone);
return user != null;
}
if (!StringUtils.isBlank(username)) {
User user = userRepo.selectUserByUsername(username);
return user != null;
}
if (!StringUtils.isBlank(email)) {
User user = userRepo.selectUserByEmail(email);
return user != null;
}
return false;
}
// 拆分成三个函数
public boolean checkUserIfExistingByTelephone(String telephone);
public boolean checkUserIfExistingByUsername(String username);
public boolean checkUserIfExistingByEmail(String email);
- 避免嵌套逻辑太深
避免if else太多的方法,可以使用卫语句,将满足条件的结果提前返回,或者使用枚举、策略模式、switch case等;
对于for循环太深嵌套,可以使用continue、break、return等提前结束循环,或者优化代码逻辑。 - 使用解释性变量
尽量不要使用魔法值,要使用常量来管理,代码中复杂的判断逻辑可以使用解释性变量,如下所示:
public double CalculateCircularArea(double radius) {
return (3.1415) * radius * radius;
}
// 常量替代魔法数字
public static final Double PI = 3.1415;
public double CalculateCircularArea(double radius) {
return PI * radius * radius;
}
if (date.after(SPRING_START) && date.before(SPRING_END)) {
// ...
} else {
// ...
}
// 引入解释性变量后逻辑更加清晰
boolean isSpring = date.after(SPRING_START)&&date.before(SPRING_END);
if (isSpring) {
// ...
} else {
// ...
}
作者:美丽的程序人生
来源:juejin.cn/post/7352079427863920651
来源:juejin.cn/post/7352079427863920651