MIT_6.031之代码审查

代码审查概述

代码审查 是软件开发过程中的重要环节,指的是开发者之间对代码进行系统、细致的审查。其主要目标是提高代码质量、发现和修复错误、提升团队的整体编程水平。代码审查帮助程序员互相学习,并确保项目一致性、可读性和可维护性。


代码审查的主要目标

  1. 改进代码:提升代码的质量,优化结构。
  2. 查找错误:提前发现潜在的 bug 或问题。
  3. 预测错误:通过阅读代码,预见可能会发生的逻辑或设计上的问题。
  4. 检查代码清晰度:确保代码易于理解、维护。
  5. 检查项目一致性:代码风格、命名规范、注释等与项目保持一致。
  6. 改善程序员:通过相互讨论代码来提高个人和团队的编程技能。
  7. 学习和教导
    • 新语言特性。
    • 项目设计技巧。
    • 编码标准和最佳实践。

良好编码的通用原则

无论使用何种编程语言或项目类型,代码审查中的一些通用规则和最佳实践始终适用:

  1. 避免重复自己(DRY, Don't Repeat Yourself)

    • 重复代码会导致同一错误在多个地方出现,维护困难。
    • 修改代码时,多个重复片段都要更新,增加出错机会。
    • 解决方法:提取出公共逻辑,用函数、方法或数据结构来简化。

    示例:修改 dayOfYear 方法:

    1
    2
    3
    4
    5
    6
    7
    public static int dayOfYear(int month, int dayOfMonth, int year) {
    int[] monthLengths = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    for (int i = 0; i < month - 1; i++) {
    dayOfMonth += monthLengths[i];
    }
    return dayOfMonth;
    }
  2. 注释

    • 良好的注释可以帮助理解代码。
    • 使用 Javadoc 风格注释记录方法或类的行为。
    • 注释可以防止 bug,因为清晰的注释可以帮助其他程序员理解代码的目的和限制。

    示例的 Javadoc 注释:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    /**
    * 计算某日期是该年的第几天。
    * @param month 月份,范围为 1 到 12。
    * @param dayOfMonth 每个月的天数,1 到 31 之间。
    * @param year 年份,用于判断是否为闰年。
    * @return 该日期是该年的第几天。
    */
    public static int dayOfYear(int month, int dayOfMonth, int year) {
    ...
    }
  3. 快速失败原则

    • 当代码出现错误时,尽可能让它早期失败。
    • 提前发现问题可以简化调试。
    1
    2
    3
    if (month < 1 || month > 12) {
    throw new IllegalArgumentException("Invalid month: " + month);
    }
  4. 避免魔术数字

    • 除了 0、1、2 这类基本常量外,其他所有数字应声明为具备清晰含义的命名常量。
    1
    2
    final int FEBRUARY = 2;
    final int DAYS_IN_YEAR = 365;
  5. 每个变量一个目的

    • 不要重用变量,每个变量应有明确的用途。
    • 尽量使用 final 修饰符使方法参数和局部变量不可变,提升代码的可读性和安全性。
  6. 使用好名字

    • 方法和变量名应具备自描述性,使用清晰明了的名称,避免使用单字符变量。
    • 方法名 通常是动词短语,表示动作。
  7. 不要使用全局变量

    • 全局变量容易引入错误,因为它们可以随时被任何地方修改。
    • 应使用局部变量,或者使用类的成员变量并控制其访问权限。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public class WordCounter {
    private static final int LONG_WORD_LENGTH = 5;
    private String longestWord = "";

    public int countLongWords(List<String> words) {
    int count = 0;
    for (String word : words) {
    if (word.length() > LONG_WORD_LENGTH) {
    count++;
    }
    if (word.length() > longestWord.length()) {
    longestWord = word;
    }
    }
    return count;
    }
    }
  8. 返回结果,不要打印结果

    • 方法应返回其计算的结果,而非直接输出,以便可以在其他地方复用该结果。
  9. 使用空格提升可读性

    • 适当使用空格分隔代码,使其更具可读性。
    • 禁止使用制表符缩进,统一使用空格。

总结

优质代码有三个关键属性:

  1. 避免错误
    • 通过代码审查和减少重复代码来降低错误发生率。
    • 提前快速失败以尽早发现问题。
    • 清晰的注释和避免全局变量有助于查找和修复错误。
  2. 容易理解
    • 清晰的注释、合适的变量名、避免魔术数字和简洁的代码结构都能让代码更具可读性。
  3. 准备好进行更改
    • 经验丰富的开发者可以通过代码审查预见可能的变更需求,并提前进行代码优化。
    • 避免重复代码和全局变量,使得代码更容易维护和扩展。