当前位置: 首页>后端>正文

编码优化性定义分享

一、代码的可读性

1.1、命名

命名随处可见,给变量、函数、参数、类和封包命名。应遵循规范文档的命名规范,并且一旦发现有更好的名称,就换掉旧的。这么做,你和读你代码的人都会更开心。

1.2、格式
  • 大括号与if, else, for, do, while语句一起使用,即使只有一条语句(或是空),也应该把大括号写上 ;
  • 空的块状结构可以简写为一行,但如果他是多块状结构的一部分,无论如何也要换行;
//空块状结构
void do(){}

if() return ;

//多块状结构
if(expression){

}else if(otherExpression){ 

}else{

}
  • 一行代码超过80个字符需要换行;
  • 一个方法函数内的代码不超过100行。
1.3、异常
  • 异常处理需要对java和spring的异常体系有所了解,并遵循对已知捕获、对未知抛出的原则,进行项目内异常体系的构建、优化;
  • 长代码块的异常需要分别处理,不要在一个try catch中进行捕获;
  • 反例:
public void test(){
        try{
                do smoething
                do smoething
                do smoething
        }catch(Exception e){

        }
}
  • 正例:
public void test(){
        try{
                do smoething
        }catch(Exception e){

        }
        try{
                do smoething
        }catch(Exception e){

        }
        try{
                do smoething
        }catch(Exception e){

        }
}
  • 循环体内不要使用try catch,需要时在循环外使用;
1.4、常量/魔术值
  • 所有常量的修饰符必须含有static final;
  • 常量的使用域需要限制在相应模块中,防止版本更迭后其他模块发生错误;
  • 代码中涉及逻辑中断和条件判断不要出现不明的、未经释义的值,需要有明确命名魔术值;
  • 反例:
public boolean hasAdminRole(List<Role> roles){
    for(Role role : roles){
        if(user.getId == 9527){
            return true;
        }
    }
    return false;
}
  • 正例:
//key角色对应的id
private static final Integer KEY_ROLE_ID = 9527;

public boolean hasKeyRole(List<Role> roles){
    for(Role role : roles){
        if(user.getId == KEY_ROLE_ID){
            return true;
        }
    }
    return false;
}
1.5、函数
  • 每一个方法函数在逻辑上应该包含明确的 输入(参数)和输出(返回值);
  • 一个方法函数需要明确的主体逻辑和次要逻辑,对于复杂冗长的函数,尽可能的展现主体逻辑,拆分次要逻辑到其他函数中,进行模块化编程;
  • 反例:
public LoginUser getUserInfo(){
    //获取用户 token
    ServletAttributs requestAttributes = RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = requestAttributes.getRquest();
    String token = request.getHeader("access_token");
    if(StringUtils.isEmpty(token)){
        throw new EmptyLoginTokenException("用户登录token获取错误");
    }
    //根据token 获取用户信息
    SysUser user = (SysUser)redisUtil.get(token);
    //转换loginUser
    LoginUser loginUser = new LoginUser();
    loginUser.setId(user.getId());
    loginUser.setAccount(user.getAccout());
    loginUser.setName(user.getName());
    ...
    //补充角色信息
    List<SysRole> roles = new ArrayList<>();
    roles = roleService.getRolesByUserId(loginUser.getId());
    if(CollectionUtils.isNotEmpty(roles)){
            Set<SysRole> roleSet = new HashSet(roles);
        roles.setRoles(roleSet);
         //补充权限信息
        List<SysPermission> permissions = new ArrayList<>();
        permissions = permissionService.getPermissionsByRoles(roles);
        if(CollectionUtils.isNotEmpty(permissions)){
            Set<SysRSysPermissionole> permissionSet = new HashSet(permissions);
            roles.setPermissions(permissionSet);
            ...
        }
    }
         return loginUser;
}
  • 正例:
public LoginUser getUserInfo(){
    //获取用户 token
    String token = getToken();
    //根据token 获取用户信息
    SysUser user = (SysUser)redisUtil.get(token);
    if(ObjectUtil.isNEmpty(user)){
         return null;
    }
    //转换loginUser
    LoginUser loginUser = convertLoginUser(user);
    //补充角色信息
    supplyLoginUser(loginUser);
         return loginUser;
}

private String getToken(){
    ServletAttributs requestAttributes = RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = requestAttributes.getRquest();
    String token = request.getHeader("access_token");
    if(StringUtils.isEmpty(token)){
        throw new EmptyLoginTokenException("用户登录token获取错误");
    }
    return token;
}

private LoginUser convertLoginUser(SysUser user){
    LoginUser loginUser = new LoginUser();
    loginUser.setId(user.getId());
    loginUser.setAccount(user.getAccout());
    loginUser.setName(user.getName());
    ...
    return loginUser;    
}

private void supplyLoginUser(LoginUser loginUser){
    List<SysRole> roles = new ArrayList<>();
    roles = roleService.getRolesByUserId(loginUser.getId());
    if(CollectionUtils.isNotEmpty(roles)){
            Set<SysRole> roleSet = new HashSet(roles);
        roles.setRoles(roleSet);
         //补充权限信息
        List<SysPermission> permissions = new ArrayList<>();
        permissions = permissionService.getPermissionsByRoles(roles);
        if(CollectionUtils.isNotEmpty(permissions)){
            Set<SysRSysPermissionole> permissionSet = new HashSet(permissions);
            roles.setPermissions(permissionSet);
            ...
        }
    }
}
1.6、嵌套
  • 一个方法函数内的嵌套不要超过三层;
  • 反例:
void render(List<User> users){
    if(CollectinUtils.isNotEmpty(users)){
       for(User user : users){
           if(CollectinUtils.isNotEmpty(user.getRoles())){
              for(Role role : user.getRoles()){
                  do something
              } 
           }
       }
    }
}
  • 正例:
void render(List<User> users){
    if(CollectinUtils.isEmpty(users)){
        return;
    }
    for(User user : users){
      if(CollectinUtils.isEmpty(user.getRoles())){
         continue;
       }
      for(Role role : user.getRoles()){
         do something         
      }   
    }
}
1.7、条件
  • 循环条件进行逻辑上的合并;
  • 合并前:
List goodNames = new ArrayList<>();
if(bool){
    for (String name: names) {
      if (name.contains("bad")) {
        continue;
      }
      goodNames.add(name);
      ...
    } 
}
  • 合并后:
List goodNames = new ArrayList<>();
for (String name: names) {
  if (!name.contains("bad")) {
    goodNames.add(name);
    ...
  }
}  
  • 多条件判断超过三个需要换行;
if(menus.contain(MenuEnums.HOME_PAGE)
          && menus.contain(MenuEnums.ERROR_PAGE)
          && menus.contain(MenuEnums.LOGIN_PAGE)){

}
  • 赋值条件为2个时尽量使用三目运算符号;
Subject sub = new Subject();
sub.setDataScope(UserContext.hasAdminRole()?"all":user.getDataScope());
1.8、边界

项目管理中,项目由进度、成本、质量和边界构成,边界是指研发过程中应完成需求对应的功能,避免不必要的过度编码,由此引发的返工问题也会回过头来影响进度、成本与代码质量。

1.9、注释
  • 遵循注释规范使用单行注释与多行注释,代码中不要使用尾注释;
  • 优雅代码应追求即使没有注释仍能被看懂的原则,通过规范的命名和简介的功能描述减少冗余注释的编写;

二、代码的可维护性

  • 编写时可维护性:是指在程序或系统上线后爆出 BUG,开发团队能够及时扑灭这个 BUG 且不会爆出其他 BUG。保持方法的原子性,提高代码内聚,能使某处修改的影响降到最低,这样某处方法出现 BUG,也不太会影响到其他模块的正常运作;
  • 运行时的可维护性:是指在系统运行过程中(或无需再次编码发布、只需系统重启一次)修改系统的某项配置并使其生效,且不影响现在正在进行的业务和用户的操作。这要求软件工程师不能把代码写死。例如配置文件、数据库连接字符串、资源文件、日志等。

三、代码的可变更性

  • 提高代码的复用:需要对整个系统的整体进行分析与合理规划,长期不断的对系统模型进行划分,对模型边界进行设定,保证每个功能被合理地划分到响应的模型的每个类中,这样可以很好地保证代码复用;
  • 设计模式:是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。

四、技术评审

技术评审包含编码前的方案评审和编码后的代码review,是代码质量管理方式的一种,以下列举代码评审阶段排排查的典型案例:

  • 功能错误
  • 资源泄漏
  • 空的异常处理、缺失日志
  • 事务的使用
  • 文档、类、方法、复杂算法注释
  • 重复代码
  • 过长的方法参数列表
  • if/while/for等嵌套3层以上
  • 无实际意义的类、方法、变量名称

https://www.xamrdz.com/backend/3jp1936113.html

相关文章: