美文网首页
编码优化性定义分享

编码优化性定义分享

作者: _Rondo | 来源:发表于2023-11-12 03:26 被阅读0次

    一、代码的可读性

    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.haomeiwen.com/subject/ofmlwdtx.html