你应该选择一套管理代码格式的简单规则。如果是团队,应该选择一套团队一致同意采用的简单格式规则。
最重要的原则:一致性(Consistency)!
- 没有完美的格式规范,但有统一的规范。 整个团队(或者你自己写项目时)要定下一套格式规则,然后所有人都要严格遵守它。哪怕某个规则你不太喜欢,为了团队整体的代码风格统一,也得遵循。
- 为什么? 读代码时,大脑就不用去适应不同的排版风格了,可以把精力完全放在理解代码逻辑上。
- 强烈建议: 使用自动化代码格式化工具(IDE 里通常都有,比如 IntelliJ IDEA 的 Reformat Code,Eclipse 的 Format),并配置好团队统一的格式规范,让工具去强制执行排版规则。
格式的目的
代码格式关乎沟通,而沟通是专业开发者的头等大事。
你今天编写的功能,即有可能在下一版被修改,而代码的可读性会对以后可能发生修改行为产生深远影响。
垂直格式(Vertical Formatting)- 像写文章一样组织代码
想象你的代码文件是一张纸,你怎么在纸上从上往下安排内容?
- 报纸头条原则: 文件顶部应该包含最高层次、最概括的概念(比如类名、最重要的功能)。越往下,代码应该越详细,越具体。就像读报纸,先看大标题、导语,再看详细报道。
- 概念之间要留白: 用空行把不相关的概念隔开,就像文章段落之间要有空行一样。
-
- 比如两个方法之间,应该用空行隔开。
- 一个方法内部,不同逻辑块之间(比如初始化变量、执行主要计算、处理结果这三个步骤)也应该用空行稍微隔开,增强可读性。
- 相关性要紧密: 关系非常紧密的代码(比如属于同一个逻辑步骤的连续几行代码)应该紧挨着,不要用空行隔开,表示它们是一个整体。
- 相关代码要靠近: 概念上相关的代码,比如调用者和被调用者、使用某个变量的代码和定义这个变量的代码,在垂直距离上应该尽量靠近。理想情况下,调用者应该在被调用者上面(回想第三章的向下原则)。很显然这条规则不使用于分布在不同文件的概念。除非有很好的理由,否则不要把关系密切的概念放到不同文件中,这也是避免使用 protected 的原因。
- 垂直距离:概念相关,概念相关的代码应该放到一起,相关性越强,彼此的距离越短。变量声明,本地变量声明尽可能靠近使用位置,实体变量应该声明在类的顶部位置,这会在大多数方法用到。函数相关,若一个函数调用了另一个函数,应该紧密的把这两个函数垂直放到一起,调用者放到函数上面,这样极大的增加了可读性,程序就有一个自然顺序。
- 文件总长度: 文件不应该无限长。如果一个文件太长(比如超过几百行),可能意味着这个类或模块承担了太多的责任,可以考虑拆分成多个文件/类。太长的文件翻起来也很费劲。
垂直顺序
一般而言,我们想自上向下展示函数调用依赖顺序。也就是说,被调用的函数应该放在执行调用的函数下面 ¹。这样就建立了一种自顶向下贯穿源代码模块的良好信息流。
像报纸文章一般,我们指望最重要的概念先出来,指望以包括最少细节的方式表述它们。我们指望底层细节最后出来。这样,我们就能扫过源代码文件,自最前面的几个函数获知要旨,而不至于沉溺到细节中。
横向格式
想象怎么把一行行的代码写得更舒服?
空格的使用:
- 在操作符两边加空格: 让代码看起来不拥挤,更容易分辨不同的元素。例如
a = b + c;
而不是a=b+c;
。 - 逗号后面加空格: 比如
method(arg1, arg2);
- 方法名和括号之间不要有空格:
methodName();
而不是methodName ();
。 - 关键字后面加空格:
if (...)
,for (...)
,while (...)
。
缩进(Indentation):这是水平格式中最重要的! 缩进表示了代码的层级结构。每一个代码块(比如 if
体、for
循环体、方法体、类体)都应该相对于其外层块进行缩进。严格且一致的缩进是代码可读性的基石。
不要对齐变量声明或赋值: 有些人喜欢让多行变量声明的赋值符号 =
对齐。虽然看起来整齐,但当你修改其中一行时,可能导致很多其他行的等号位置也需要调整,这在代码版本管理(Git Diff)时会产生很多不相关的修改,干扰 Code Review。
空范围
如果循环语句块为空,不要在结尾加分号,容易看不见,你可以就用空括号,确保缩进,或者换行加 ;,这样也有点丑