常见编码规范

时间:2023-02-02 16:07:39

命名规范

命名长度

命名的原则以准确达意为目标,其长度以遵循此原则为主,并且是越短越好。

  • 对于公认、熟知的词,可以在项目内部统一成缩写
  • 对于作用域较小的变量,可以使用较短的命名
  • 对于作用域较大的变量,推荐使用可达意的较长的命名

命名上下文

命名时可以根据上下文来简化命名,如在 User 类中,就不需要对类中的成员变量添加 user 前缀,而是直接命名如 namepassword 等名称。

在使用时,开发者也可以借助上下文明确变量的含义。

可读性

可读性指的是不使用特别生僻、难发音的英文单词来命名,同时也不要使用一些无意义、随意搭配的单词。

可搜索性

命名可搜索性指的是,使用 IDE 开发的时候,可以很方便地使用“关键词联想”功能快速补全。

这个原则指的是,最好能在项目、团队内部统一命名方式,如都使用 selectXXX 表示查询,而不是既有 selectXXX,也有 findXXXqueryXXX 等多种命名方式表示查询。

接口、抽象类

对于接口的命名,通常有两种比较常见的方式:一种是接口加前缀 I 表示 Interface,如 IUserService;另一种是实现类加后缀 Impl 表示 implements,如 UserServiceImpl

对于抽象类的命名,也有两种常见的方式:一种是带上前缀 Abstract 表示抽象类,如 AbstractConfig;另一种是不带前缀。

无论是接口还是抽象类,选择哪个命名方式都可以,最重要的是能在项目内部统一。

注释规范

注释内容

注释的目的是让代码更容易看懂。

注释的内容主要是包括三个方面:做什么、为什么做、怎么做。对于复杂的接口或类,还需要补充“如何用”。

注释多少

注释本身有一定的维护成本,并非越多越好。

类和函数一定要写注释,而且要写得尽可能全面、详细,函数内部的注释要相对少一些,一般可以通过好的命名、提炼函数、解释性变量、总结性注释等方式来提高代码可读性。

代码风格

类和函数的行数

对于函数代码行数的最大限制,网上有一种说法:最好不要超过一个显示屏的垂直高度。

对于类的代码行数的最大限制,有一个间接的判断标准:

  • 当一个类的代码读起来比较困难
  • 实现某个功能时不知道该用哪个函数
  • 想用哪个函数的时候需要找很久
  • 只用到一个小功能的时候要引入整个类

一行代码的长度

总体遵循一个原则:一行代码最长不能超过 IDE 显示的宽度。

需要滚动鼠标才能查看一行的全部代码,显然不利于代码的阅读;但是太小的限制也会导致很多稍长点的语句被折成两行。

分隔单元块

对于比较长的函数,如果逻辑上可以分为几个独立的代码块,但是又不方便将这些独立的代码块抽取成小函数的时候,可以使用总结性注释的方式分隔代码块。

除此之外,还可以通过使用空行分隔代码块。如类的成员变量和函数之间、静态成员变量和普通成员变量之间、各函数之间、甚至是各成员变量之间。

类成员的排列顺序

在 Google Java 编程规范中,依赖类按照字母序从小到大排列、类中先写成员变量后写函数、成员变量之间或函数之间先写静态成员变量或函数(按照作用域大小依次排列)。

常用技巧

善于提炼函数

对于逻辑比较复杂的代码,通常是建议提炼出类或者函数,但也避免提炼出的函数只包含两三行代码,以增加阅读成本。

避免函数参数过多

通常函数的参数超过 5 个时候就会影响到代码的可读性,使用起来也不方便。

出现函数参数较多的情况,通常有两个解决办法:根据单一职责原则拆分成多个函数;将函数的参数封装成对象。

勿用函数参数控制逻辑

切勿在函数内部根据函数的参数来控制内部逻辑,如根据 isVip = true 时走 VIP 的逻辑、isVip = false 走非 VIP 的逻辑。

针对于这样情况,通常是根据需求将其拆分成多个函数,拆分之后的函数职责更明确。

函数设计要职责单一

不只是针对类、模块而言,对于函数的设计,更要满足单一职责原则。

移除过深的嵌套

代码嵌套最好不超过两层,超过两层之后就要思考一下是否可以减少嵌套,以避免难以理解和代码缩进过多。

解决代码嵌套过深的方法有以下几种思路:

  • 去掉多余的 if 或者 else 语句
  • 使用编程语言提供的 continuebreakreturn 关键字提前退出嵌套
  • 调整执行顺序来减少嵌套
  • 将部分嵌套的逻辑封装成函数调用,以此来减少嵌套
  • 使用多态来替代 if-elseswitch-case 条件判断

使用解释性变量

使用解释性变量可以提高代码的可读性,常见的情况有以下几种:

  • 使用常量取代魔法数字
  • 使用解释性变量来解释复杂表达式

函数错误返回

函数的运行结果可以分为两类:正确情况下输出的预期结果,异常(出错)情况下输出的非预期结果。

在异常情况下,函数返回的数据类型非常灵活,可以针对不同的场景和特点选择不同的返回值。

返回错误码

C 语言没有异常这样的语法机制,返回错误码是最常见的出错处理方式。

而 Java、Python 等比较新的编程语言,大部分情况下,都用异常来处理函数出错的情况,极少会用到错误码。

返回 NULL 值

在多数编程语言中,使用 NULL 值表示“不存在”这种语义。

对于查找函数来说,数据不存在并非一种异常情况,是一种正常行为,所以返回表示“不存在”语义的 NULL 值比返回异常更加合理。

返回空对象

返回 NULL 值有各种弊端,对此有一个比较经典的应对策略,那就是应用空对象设计模式。

当函数返回的数据类型是字符串类型或者集合类型的时候,可以用空字符串或空集合替代 NULL 值,来表示不存在的情况。

抛出异常对象

最常用的函数出错处理方式是抛出异常。异常可以将正常逻辑和异常逻辑的处理分离开,这样的代码可读性会更好。

对于抛出的异常对象,通常有以下几种处理方式:

  • 直接吞掉,如在捕捉之后只记录日志,不做任何处理
  • 原封不动的重新抛出,如在调用的函数外部重新抛出相同的异常
  • 包装新的异常重新抛出,如在捕捉之后抛出另一个的异常