快速改善代码质量的20条编程规范


快速改善代码质量的20条编程规范

1.关于命名

  • 命名的关键是能准确达意(不要刻意选择一些缩写命名 不好理解)
  • 借助类的信息来简化属性、函数命名
    //优化前
    public class User {
        private String userName;
        private String userPassword;
        private int userAge;
    }
    //优化后
    public class User {
        private String name;
        private String password;
        private int age;
    }
  • 命名要可读、可搜索
    • 比如查询方法统一用getxxx()方便输入.get的时候联想搜索
    • 统一规范,比如统一用addxxx()而不是insertxxx()来表示插入一条数据
  • 接口和抽象类特殊命名
    • 接口:一种是在接口中带前缀”I”,另一种是在接口的实现类中带后缀”Impl”
    • 抽象类:可以加上”abstract”前缀
      //接口命名1
      public interface IUserService{}
      public class UserService implements IUserService{}
      
      //接口命名2
      public interface UserService{}
      public class UserServiceImpl implements UserService{}

2.关于注释

  • 注释需要写什么内容?
    • 做什么
    • 为什么
    • 怎么做
    • 如何用(针对较复杂的类和接口)
  • 注释是不是越多越好?
    • 注释太多,会影响代码的阅读
    • 注释太多,会影响后期的维护成本(改代码需要同步修改注释,否则会对不上)
  • 哪里写注释比较好?
    • 类和函数一定要写注释(尽可能全面、详细)
    • 函数内部注释相对少一点(依赖好的命名、提炼函数等提高代码可读性)

3.函数、类多大才合适?

  • 尽量不要超过一个屏幕大小

4.一行代码多长最合适?

  • 尽量不要超过IDE显示的宽度(否则得左右拉不方便看)
  • 也不要太短,不然一句代码容易被拆成多长,也不利于阅读(也不整洁)

5.善用空行分割单元块

  • 长函数里不同独立逻辑的代码块可以用空行分割(简洁、清晰,方便阅读也方便后续维护)
  • 其他场景也可加空行分割
    • 类的成员变量和函数之间
    • 类的静态成员变量和普通成员变量之间
    • 类的各函数之间
    • 类的各个成员变量之间
      public class UserService {
        @Autowired
        private UserMapper userMapper;
      
        @Autowired
        private NoticeService noticeService;
      
        public boolean login(int id) {
          //获取用户信息
          User user = userMapper.selectById(id);
          if(user == null) {
            return false;
          }
      
          //登陆成功下发消息
          boolean result = noticeService.sendLoginSuccess(user);
          return result;
        }
      
      }

6.四格缩进还是两格缩进?

  • 推荐用两格缩进(节省空间,Java倾向于两格)
  • 取决个人喜好/团队统一即可

7.大括号是否要另起一行?

  • 不另起一行:节省代码行数(推荐)
  • 另起一行: 左右括号可以垂直对齐(代码块一目了然)

8.类中成员的排列顺序

  • :成员变量->函数
  • 成员变量/函数:静态成员变量/函数->普通函数/函数
  • 个人习惯:比较喜欢把成员变量放前面,函数放后面(每个public和依赖的private方法放一起)

9.把代码分割成更小的单元快

  • 背景:我们一般看某个函数都是先看这个函数整体是什么功能,再看步骤(如果一行行看容易浪费时间而且不一定看得懂)
  • 建议:拆分成多个独立功能的小函数
  • 优点:方便阅读、易扩展
    //优化前
    public class UserService {
      public void bigMethod(){
        //逻辑1 第一行
        //逻辑1 第二行
        //逻辑1 第三行
        //逻辑1 第四行
    
        //逻辑2 第一行
        //逻辑2 第二行
        //逻辑2 第三行
    
        //逻辑3 第一行 
      }
    
    }
    
    //优化后
    public class UserService{
      public void bigMethod() {
        this.smallMethod1();
        this.smallMethod2();
        this.smallMethod3();
      }
      public void smallMethod1(){
        //逻辑1 第一行
        //逻辑1 第二行
        //逻辑1 第三行
        //逻辑1 第四行
      }
      public void smallMethod2(){
        //逻辑2 第一行
        //逻辑2 第二行
        //逻辑2 第三行
      }
      public void smallMethod3(){
        //逻辑3 第一行 
    
      }
    }

*10.避免函数参数过多

  • 根据不同逻辑拆分多个函数

    public class UserService {
      //优化前
      User getUser(String username, String phone);
    
      //优化后
      User getUserByUsername(String username);
      User getUserByPhone(String phone);
    }
  • 将函数参数封装成对象

    public class UserService {
      //优化前
      boolean register(String username,String password,int sex,String phone,String email);
      //优化后
      boolean register(User user);
    }
    
    public class User{
      private int id;
      private String username;
      private String password;
      private int sex;
      private String phone;
      private String email;
    }

11.勿用函数参数来控制逻辑

  • 不要用boolean值控制内部逻辑(true走一个逻辑、false走另一个逻辑)
    //例子:根据男女生做不同逻辑处理(分场景,不一定适用其他场景)
    public class UserService {
      //优化前
      void login(String username, boolean isMale);
      //优化后
      void loginForMale(String username);
      void loginForFemale(String username);
    }

12.移除过深的嵌套层次

  • 去掉多余的if/else语句
  • 使用continue、break、return等提前退出嵌套
  • 调整执行顺序来减少嵌套(如提前判空再执行正常逻辑)
  • for循环独立逻辑可抽出为一个个函数(参考自《重构改善既有代码的设计》)

13.学会使用解释性变量

  • 常量取代魔法数字

    public class UserService {
      //计算不同单位的毫秒值
      public static final long ONE_DAY = 24 * 60 * 60 * 1000;
      public static final long ONE_HOUR = 60 * 60 * 1000;
      public static final long ONE_MINUTE = 60 * 1000;
    }
  • 使用解释性变量来解释复杂表达式

    //比如该例子的isToday就是解释性变量
    public class UserService {
      public void test() {
        //判断是否当天
        boolean isToday = this.isBefore(24) && this.isAfter(0);
        //...
      }
    }
    
    public class Time {
      public boolean isBefore(int hour) {
        //...
      }
    
      public boolean isAfter(int hour) {
        //...
      }
    }

文章作者: GaryLee
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 GaryLee !
  目录