代码洁癖系列(五):外在的格式美

我们在阅读一些优秀项目的源码时,一定会感叹他们代码的整洁和一致性。而作为第一印象,代码格式的整齐是让人能够继续阅读下去的动力。今天我们分别从垂直格式和横向格式两个方面来讨论代码的格式。修正格式的方法有:间隔、靠近和调整顺序。

垂直格式

在垂直格式方面,我们要向报纸的排版学习。

newspaper

首先有一个标题告诉你这栏新闻要讲什么,好让你知道是否要继续阅读下去。对应到代码中就是类的名字,我们要力求只通过名字就可以知道这个类要描述什么事情;然后,代码的第一段往往都交代了整个故事的概要,类似于代码中的接口,我们往往通过接口了解类中有哪些函数,每个函数都是干什么的。了解了这些之后,才会去读详细的内容。

newspaper code
标题 类名
第一段 接口
内容 方法体

此外,还需要注意的就是报纸的排版、段落和段落之间用空行做间隔。写代码也可以用同样的方式,例如,我们习惯于在包声明、导入声明和每个函数之间用空白行来分隔。我们直接拿代码来解释。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.thoughtworks.selenium;

import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.internal.IResultListener;

import java.io.File;

public class ScreenshotListener implements IResultListener {

File outputDirectory;
Selenium selenium;

public ScreenshotListener(File outputDirectory, Selenium selenium) {
this.outputDirectory = outputDirectory;
this.selenium = selenium;
}

public void onTestFailure(ITestResult result) {
Reporter.setCurrentTestResult(result);

try {
outputDirectory.mkdirs();
File outFile = File.createTempFile("TEST-" + result.getName(), ".png", outputDirectory);
outFile.delete();
selenium.captureScreenshot(outFile.getAbsolutePath());
Reporter.log("<a href='" +
outFile.getName() +
"'>screenshot</a>");
} catch (Exception e) {
e.printStackTrace();
Reporter.log("Couldn't create screenshot");
Reporter.log(e.getMessage());
}

Reporter.setCurrentTestResult(null);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.thoughtworks.selenium;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.internal.IResultListener;
import java.io.File;
public class ScreenshotListener implements IResultListener {
File outputDirectory;
Selenium selenium;
public ScreenshotListener(File outputDirectory, Selenium selenium) {
this.outputDirectory = outputDirectory;
this.selenium = selenium;
}
public void onTestFailure(ITestResult result) {
Reporter.setCurrentTestResult(result);
try {
outputDirectory.mkdirs();
File outFile = File.createTempFile("TEST-" + result.getName(), ".png", outputDirectory);
outFile.delete();
selenium.captureScreenshot(outFile.getAbsolutePath());
Reporter.log("<a href='" +
outFile.getName() +
"'>screenshot</a>");
} catch (Exception e) {
e.printStackTrace();
Reporter.log("Couldn't create screenshot");
Reporter.log(e.getMessage());
}
Reporter.setCurrentTestResult(null);
}
}

是不是适当增加空白行就提高了代码的可读性呢,这里说的是适当增加空白行,并不代表随意增加。事实上,如果增加一些无意义的空白行反而会使代码的可读性变差。

我们习惯于使有关联的代码彼此靠近,无明显关联的代码相互分隔。因此我们不但需要使用空白行间隔代码,还要调整代码位置,把有关联的代码放在一起,通常我们把被调用的函数放在调用函数的下面。这样别人在读我们的代码的时候再也不用经历来回“跳跃”的痛苦了。

最后,我们通常把实体变量定义在类的顶部,这个只是我们Java程序员的习惯操作,如果突然在类的中间位置出现一个变量声明会让人觉得很奇怪。如果你想说,定义在中间是不想让定义位置和调用位置离太远,那么只能说明你的类定义出现了问题。建议你看一下旧文代码洁癖系列(三):整洁的类和函数

横向格式

介绍完垂直格式,紧接着自然要来介绍一下它的兄弟,横向格式。或许你会问为什么不叫水平格式,我的回答是:也可以叫水平格式,只要你喜欢。横向格式也是需要间隔和靠近的,这里的间隔主要是为了起到强调的效果。举个例子。

1
int lineSize = line.length();

这里等号两边的空格分别是为了强调左右两边的元素。横向格式另一个比较重要的元素就是缩进,Java程序对缩进没有强制性要求,而Python程序对缩进的要求非常严格,稍有不慎,执行的结果就会不同。但是Java程序员也要注意缩进,因为我们的代码是层级关系,而缩进可以帮我们快速理清层级关系。

最后,横向代码格式对每行代码长度是有要求的,如果代码过长,那么在阅读的时候就需要左右滑动,而这个操作其实是不受人喜欢的。虽然现在代码编辑器可显示的长度变大了,但我们还是习惯每行代码最多100个字符。

团队的规则

每一个优秀的团队都已一套属于自己的代码格式要求,有些是特定的,有些是使用公共的。我们team所用的代码规范就是Google的代码规范,阿里的代码规范也是比较被大家认可的。这里给大家一个小福利,在我的公众号后台回复【代码规范】,就可以获得一份阿里的Java开发手册。

Jackey Wang wechat
欢迎关注我的公众号,一起讨论如何写bug
-------------本文结束感谢您的阅读-------------
原创不易,感谢支持