杂谈[代码] 如何提高代码可读性的总结

116 阅读5分钟

编码已经好几年了,在这段时间自己也总结了一些如何提高代码可读性的总结,不涉及设计,抽象,封装等泛泛而谈的概念,主要从下面几个方面进行分析

  1. 命名
  2. 注释
  3. 代码格式
  4. 方法长度
  5. 重复编码
  6. 避免if else 深层嵌套
  7. 避免回调地域
  8. 方法抽取
  9. 尽量使用稳定的新特性
  10. ts禁止使用any,除非是对万能函数进行传递封装

命名

命名是一个最基础的技能,在我看来命名是最重要的,一个好的命名是不需要使用注释来解释函数功能的

目前现有的命名规范包括

  • 驼峰命名法:单词首字母区分大小写,分为小驼峰和大驼峰nameName NameName
  • 蛇形命名法:使用下划线分割,一般小写,linux内核中代码文件命名方法name_name
  • 匈牙利命名法:属性+类型+描述g_int_change
  • 帕斯卡命名法:首字母全部大写,常用于类名NameName ClassName
  • 脊柱命名法:使用中划线分割,常用于文件夹,linux内核中文件夹命名方法name-name
  • 自由命名法:无规则NameName NameN
  • 驼峰蛇形命名法:驼峰和蛇形命名结合的写法name_Name Name_Name

我们可以看到命名方式有很多种,但是我们一般开发命名是需要根据不同的变量类型定义不同的书写方式

  • 普通类: 使用 大驼峰 如 ClassName
  • 接口:接口我一般会使用大驼峰并在尾部加I表示接口 如 InterfaceNameI
  • 接口实现类: 接口实现类通过大驼峰+Impl表示接口实现类 如ClassNameImpl
  • 常量: 常量分为公共常量和局部常量,如果是公共常量,我会使用全大写+蛇形命名法 如CONST_NAME
  • 枚举:在Java中,枚举是使用大驼峰命名,而枚举值使用大写字母命名 如 EnumName,枚举变量使用 EnumName.VALUE,在C中,枚举和变量全大写
  • 普通变量:普通变量使用小驼峰命名方法 如 valueName
  • 方法: 使用小驼峰命名,并且命名方式是:描述+参数,如queryUserListByIdinsertUserById

注释

注释是用来增强描述变量或方法的功能含义或流程

注释的命名分为 行注释//和块注释/**/

行注释一般对单个变量进行修饰

// 注释
int age = 20; // 注释

块注释一般会被编辑器解析成提示描述,一般描述类方法所需的特性和主要功能

/**
* 功能描述
* @author 作者
* @date   创建时间
*/
class ClassName {}

/*
* <p>
* 根据用户id返回用户信息
* @param id
* @return User
* </p>
**/
List<User> queryUserListById(Integer id) {}

代码格式/方法长度/方法抽取

这里指的代码格式指的是代码的空格分隔变量声明等,如果是javascript还得包括单双引号,结尾分号,tab空格,对象结尾逗号等,这里说通用设置

我一般会将使用到的同一作用域的变量声明在顶部,如果变量可以直接初始化而且不需要改变其值,则使用const进行修饰

在如果代码块是顺序执行的,则按照功能使用空格分割,并注释代码的功能,若处理逻辑超过5行,则抽取该逻辑为一个函数作为独立的功能,保持每个函数的精简。尽量控制每个方法块代码小于20行

重复编码

对于重复编码,我的方式就是抽取公用逻辑进行封装,如果使用的场景比较多,则考虑抽取到公共工具函数中,如果只是该方法使用,则在这个类或模块中声明即可

避免if/else深层嵌套

当我们编写一段逻辑的时候,很难不使用分支逻辑,针对该逻辑,如果是针对变量的单一处理,则首先处理变量不满足条件的情况,如果可以直接返回就返回或者跳过,使处理逻辑和判断逻辑为同一块级作用域。

针对多值判断,尽量写在一个判断逻辑中,并使用逻辑符合进行判断,减少嵌套深度。

回调地域

回调地域是JavaScript中常见的问题

如果是针对异步处理,我会使用async/await流程化,但是使用这种方式一定要处理好异常,或使用withResolvers进行封装,将其转化为顺序执行。

如果是普通函数,则尽量将任务返回,或提供一个添加回调函数的变量,避免回调地域

使用稳定的新特性

我是比较喜欢使用新方法的,首先对于社区的发展,新的特性必然是解决已有痛点问题,或者可以简化编程,而且新特性必须要熟练使用,如一个经典场景

在ES6 数组stream处理函数还未出来的时候,我们需要借助for循环来完成数组的批量操作,这样处理是没有可读性的,而stream流式处理提供了批处理的语义化。

浏览器中的Date日期类型,随着API的不断完善,我们渐渐地可以抛弃moment,dayjs等库,但是如果涉及到复杂时间计算而且特性还没支持,则需要使用这些库来处理问题,提升编码清洁度

ts禁止使用any

这个问题也是老问题了,究其原因还是对ts提供的类型机制不了解,或者懒得定义类型,虽然开发一时爽,但是事后火葬场,不多评论,靠自觉吧。