如何写出格式清晰的代码

代码格式的意义

代码是用来描述业务逻辑的表达语言。而代码的格式则是为了更精准地表达业务逻辑。

有的人可能会认为,无论多么的难以阅读,只要能完成产品预定的业务逻辑,就是好的代码。我认为这个想法是不对的。主要原因在于,在大型项目和持续维护的过程中,以及其他人在进行 backup 的时候,比起当时的业务逻辑是否准确,能否让人理解你的意图更加重要。而代码格式便是服务于此:

为代码提供额外的上下文信息。

尽管当前各种现代 IDE 提供了方便的格式化操作。但是这种格式化主要是针对一些简单的格式比如:

  • 元素之间的空格

  • import 的位置

  • 括号之间的缩紧

尽管上述这些在实际各种中也很重要,由于有 IDE 的辅助,我们可以减少一些对于这方面的关注。

注:但是建议调整格式的时候单独提交 commit,否则与万一与业务提交混合在后续比对修改点的时候就比较恶心。

代码格式总则

如同上文所说的,代码格式是为了提供代码业务之外的上下文信息。那么在这里我们就可以明确一下代码格式提供这个信息的意义:

代码格式为代码提供符合人们阅读直觉的额外信息。

当然,这个人类阅读直觉不同的语言可能不一样,这里指的是大多数 Java 软件中使用的规则。而这里我列举一些主要值得注意的点,主要有:

  • 从上往下阅读

  • 相同内容聚集

  • 概念间分割

从上往下阅读

由于人们的阅读顺序是从上到下,从左到右的方向,所以人们常常会假定逻辑顺序也是如此的。一般来说可以有:

变量在前

Java 中的类属性一般在前面。而在方法中也一般建议将所使用到需要声明的变量,这样便于在阅读方法的时候对于接下来会出现的变量一目了然。同时,如果你发现变量与实际使用的距离太远了,那说明这个方法的行数太长了,应该优先确认一下是否可以抽取方法。

调用在前

由于人们的阅读顺序会暗示逻辑顺序,所以对于调用的方法,最好在被调用方法的上面。当然了,如果不能全部满足这种情况的话,至少区分一下主次。如果大体满足这个排序逻辑后,整体 java 文件会呈现一种:主要对外提供逻辑在前,内部被调用逻辑在后的情况。那么当开发人员浏览 java 文件的时候,应该在浏览上层的 public 方法的时候,就大概知道类的大概流程了(因为被调用的私有方法的主要信息,可以通过方法名在调用方法中提供出来)。

相同内容聚集

对于业务逻辑来说,如果存在一些关系紧密的概念的话,那么他们就应该被尽量地放在一起。这样的好处是当开发想确认是否存在某一逻辑时,可以根据已有的知识在附近检索就可以了。

而他们的关联性越强就更应该放到一起,例如方法之间、或者同时使用某个变量。以StringUtils中的部分代码来举例子:


可以看到图中的方法可以分为Empty,Blank两组,然后又各自根据单个参数、序列入参可以分为两组。如果开发根据提示只看见了isEmpty()方法的话,那当他点进来的时候就可以很轻松的根据上下文来选择自己需要的方法来使用了。

概念间分割

概念分割的意义在于,利用空行的存在,将一整段的逻辑进行分段。这样人们将很容易地把注意力集中在各个字分段的首行上,从而从各个分段的模块中检索到自己关心的逻辑。

一般这种的意义分为两种:

一种是类中的分割,这种就是 package、import、class 等部分的分割,但是因为这种的一般由 ide 来快速辅助完成,所以就也不太用关心。

另一种是在方法内进行区分。在方法内,根据各部分代码的职能来划分,以之前的相应流的代码来举例:


代码中根据注释将不同的业务进行了分割,那么我看到了创建 S1,后面的三行就可以直接忽略了,因为一目了然他们是一个部分的逻辑,然后就可以直接跳跃到订阅部分的逻辑。

而要注意的是,由于代码本身也会对代码逻辑进行分割,所以要合理地使用注释避免反而破坏代码逻辑的整体性。

工具设置

现在 Java IDE 都有辅助格式化的操作,在 IDEA 中快捷键为:option + command + L

而也可以在设置在 git 提交前进行自动格式化,配置如下:


但要注意可能会干扰 commit 时的逻辑修改点,建议单独的进行格式化。

或者还有一款Save Actions Plugin的插件,可以帮你在编辑时自动格式化。

最后

每个团队都有一套自己的代码格式规范。比如代码格式的宗旨是为了让开发了解业务的时候更加的明确。比如原先团队时就有过建议,每次都将新增方法放在类的最后,目的是便于直接地判断出问题是否由新代码引起的。但是在 IDE 有 git 提交提示的今天,我认为这种情况会导致其他代码格式更加混乱。但不论如何,只要全团队的人员可以认同同一种代码格式,保证沟通顺畅,则这个格式就是有意义的。

本文文字及图片出自 InfoQ

你也许感兴趣的:

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注