1. 引言

无论你是经验丰富的开发人员还是刚入门的新手,大概率都接触过变量和函数命名的格式规范,比如 camelCasePascalCasesnake_casekebab-case 等。

这只是众多代码格式规范中的一小部分。除此之外,还有诸如文件行数限制、缩进风格、方法与类的排布规则等。每种编程语言也有其特定的语法要求。

在本文中,我们会讨论一些实用的代码格式规范,帮助提升代码可读性。✅ 团队协作中,代码是成员之间的沟通工具,仅让程序跑起来是不够的,维护性差会带来严重问题。

我们将聚焦于如何写出结构清晰、易于理解的代码。文中示例使用 Java 编写,但其中的理念适用于任何语言。


2. 垂直格式规范

编写整洁代码时,一个经典的类比是“报纸式阅读”:我们先看标题,再看摘要,最后根据兴趣决定是否深入了解细节。

同理,文件标题和关键逻辑应出现在代码顶部,便于快速理解整体结构。那些用于实现细节的小函数和变量则应放在后面。

2.1. 垂直密度

如果一段代码表示一个完整概念(例如 HTML 渲染字符串),我们应在它与相邻代码块之间留出空行,这就是所谓的“概念间垂直开放”。

而“垂直密度”则强调:如果代码行之间逻辑紧密,就不要人为插入空行打断阅读流。

来看一个反面例子:

package fitnesse.wikitext.widgets;
import java.util.regex.*;
public class BoldWidget extends ParentWidget {
    public static final String REGEXP = "'''.+?'''";
    private static final Pattern pattern = Pattern.compile("'''(.+?)'''", Pattern.MULTILINE + Pattern.DOTALL);
    public BoldWidget(ParentWidget parent, String text) throws Exception {
        super(parent);
        Matcher match = pattern.matcher(text);
        match.find();
        addChildWidgets(match.group(1));}
    public String render() throws Exception {
        StringBuffer html = new StringBuffer("<b>");
        /**
        * Adds the HTML closing tag
        */
        html.append(childHtml()).append("</b>");
        return html.toString();
    }
}

这段代码完全没有垂直开放,所有内容挤在一起,还插入了一段无意义的注释打断逻辑流。

来看优化后的版本:

package fitnesse.wikitext.widgets;

import java.util.regex.*;

public class BoldWidget extends ParentWidget {
    public static final String REGEXP = "'''.+?'''";
    private static final Pattern pattern = Pattern.compile("'''(.+?)'''",Pattern.MULTILINE + Pattern.DOTALL);

    public BoldWidget(ParentWidget parent, String text) throws Exception {
        super(parent);
        Matcher match = pattern.matcher(text);
        match.find();
        addChildWidgets(match.group(1));
    }

    public String render() throws Exception {
        StringBuffer html = new StringBuffer("<b>");
        html.append(childHtml()).append("</b>");
        return html.toString();
    }
}

优化后的代码结构清晰,一眼就能看出每个部分的用途。

想象一下,如果整个项目文件都像第一个版本那样写,即使作者本人,几个月后再看也可能一头雾水 ❌。

2.2. 垂直距离

为了减少读者的查找成本,相关代码应尽可能放在一起。尤其是变量声明,应尽量靠近其使用位置,特别是只在某个作用域内使用的局部变量。

举个例子,假设你定义了一个处理公司员工信息的类,包括构造函数和属性赋值。接着你又写了一个生成随机值的类用于测试。如果构造函数定义在 500 行之后甚至另一个文件中,那对读者来说就是一种折磨 ❌。

2.3. 垂直顺序

代码的顺序应该反映其依赖关系。读代码时,应能自然理解上下文。

如果一个高层函数调用了低层函数,建议先写高层函数,后写低层函数,这样读者看到调用时不会急着跳到别处找定义。


3. 水平格式规范

代码行的长度应该控制在多少字符以内?一个传统做法是参考 1890 年美国人口普查用的打孔卡片,每行 80 字符。

但这个数字不应成为硬性规定,尤其在现代框架中,函数名可能本身就很长(比如 iOS 中的方法名)。

Linus Torvalds 也曾公开反对这种限制,认为长行在某些场景下更自然。因此,没有统一标准,但我们可以参考一些通用建议

3.1. 水平开放与密度

随着显示器分辨率的提升,我们可以参考 Uncle Bob 的建议:

每行代码控制在 100~120 字符之间,避免水平滚动

像赋值操作符这样的关键位置应使用空格分隔,以增强可读性:

public class CountCharsInString {
    public static void main(String[] args) {
        String exampleString = "This is just a sample string";
        long totalCharacters = exampleString.chars().filter(ch -> ch != ' ').count();
        System.out.println("There are total " + totalCharacters + " characters in exampleString");
    }
}

注意函数名与括号之间不需要空格,因为它们是强关联的。

3.2. 水平对齐与缩进

水平对齐不是必须的,有时甚至会误导阅读顺序。比如下面这种强行对齐的写法:

public FitNesseExpediter(Socket s,
                         FitNesseContext context) throws Exception
{
    this.context =            context;
    socket =                  s;
    input =                   s.getInputStream();
    output =                  s.getOutputStream();
    requestParsingTimeLimit = 10000;
}

读者可能会先看到变量名,而不是它们的赋值内容,容易产生混淆。

缩进才是代码结构的核心

源码本质上是层级结构,缩进可以帮助读者快速识别代码块的归属关系。比如下面这个没有缩进的例子:

public class Factorial{    public static void main(String[] args){    final int NUM_FACTS = 100; for(int i = 0; i < NUM_FACTS; i++) System.out.println( i + "! is " + factorial(i));}
public static int factorial(int n){ int result = 1;for(int i = 2; i <= n; i++) result *= i; return result;}}

几乎无法阅读 ❌。

而加上缩进后,结构一目了然:

public class Factorial{
    public static void main(String[] args){
        final int NUM_FACTS = 100;
        for(int i = 0; i < NUM_FACTS; i++)
            System.out.println( i + "! is " + factorial(i));
        }
        
    public static int factorial(int n) {
        int result = 1;
        for(int i = 2; i <= n; i++)
            result *= i;
        return result;
    }
}

4. 总结

虽然我们有自由选择代码格式,但必须意识到:别人将来可能会阅读甚至修改你的代码。团队协作时,应统一规范,保持项目风格一致,提升可维护性。

正如 Robert C. Martin 在《Clean Code》中所说:

“编码风格和可读性不仅影响当前代码,更会在项目演化过程中持续影响可维护性和可扩展性。你的风格和纪律会比你的代码活得更久。” ✅


原始标题:Clean Code – Formatting