注册

Java程序员快速提高代码质量建议

1、概述

相同的业务需求不同层级的程序员实现方式不一样,经验稍微欠缺一点的新手程序员,可能单纯的实现功能,经验丰富的程序员,开发的代码可能会具有很好的扩展性、易读性、健壮性。相信很多小伙伴在工作团队中,有时候会一起code review,互相review代码,其实review代码时大家保持开放包容心态,是一种团队进度的方式。
今天分享的内容主要帮助大家从代码规范的角度,梳理出快速提升代码质量的建议,学完之后可以帮助大家在团队code review时,提供建议,帮大家写出高质量代码。


2、什么样的代码是高质量代码

如何评价一段代码的好与坏,其实是有一定主观性的,不同人有不同的标准和看法,但是总的概括下来优秀的代码一般具有如下特点:


高质量代码特点.png


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 代码风格

良好的代码风格,可以提升代码可读性,主要梳理以下几点:


良好的代码风格.png


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

0 个评论

要回复文章请先登录注册