【公共规范】注释!必须要有详细的注释!

要求:

  1. 必须有详细的注释(空)

  2. 每个类(文件)必须注释清楚:

    1. 设计目的

    2. 使用场景

    3. 使用方式甚至使用样例

    4. 注意事项

  3. 每个属性、常量都要有注释。当语言支持的时候,常量有能显示出的值的时候,需要同时提供常量的值(如Java中使用@value)

  4. 每个方法,必须要注释:

    1. 一句话简要描述

    2. 详细使用描述。包括注意事项,甚至使用样例。对于Java如果沿用接口注释,可以使用@inheritdoc,但接口必须有详细注释。

    3. 返回值。必须说明可能的返回值(范围)及其对应场景

    4. 异常情况。必须说明在什么情况下可能会出现什么异常

  5. 对于重要方法,必须按步骤写清楚算法和执行逻辑

  6. 代码行注释。 尽量多的行注释,写有效的注释:要用业务逻辑来注释,而不是对代码本身注释

  7. 必须用语言提供的标准注释方式,如Java中必须用JavaDoc的注释以及支持的注解

  8. 需要考虑到注释显示时的格式。如Java的注释最终是以HTML方式呈现,所以HTML展现时会忽略回车(换行)、连续空格等,因此不能简单考虑源码中能够看得过去。

  9. 对于自己有疑问、有缺陷、有改进意见、有陷阱等等等等一切觉得对之后阅读维护代码有益的信息,都可以也强烈推荐写上

写注释的时机:

  1. 行注释。可以先写代码,然后写注释

  2. 其他注释。必须先写注释,后写代码

  3. 必须保证代码与注释一致。如果要修改代码,那么必须先修改注释,然后再修改代码

大家肯定看到过这样的理论或者说法:注释是不必要的,代码即注释!

肯定也很欣赏这个理论。但是,对不起,这个说法在我们这里不成立!

任何东西都有场景,说这句话的人的场景是:

  1. 团队水平很高

  2. 成员水平一致

  3. 思维方式一致,或者说高大上一点“程序观一致”

前面的要求提到了一点“要用业务逻辑来注释,而不是对代码本身注释”,举例说明:

final List<Task> tasks = taskService.getSortedTask(BY_PRIORITY); //获取排序task列表
final Task firstTask = tasks.get(0); // 取列表的第一个元素
task.done(); // 调用done方法

final List<Task> remains = new ArrayList<>(9); //创建一个列表
for (int i = 1; // 1 赋值给 i
	i < 10 || i < task.size(); // i 小于 10 或者 i 小于 size时
	i ++) { // i 加一
	final Task task = task.get(i); // 取列表元素
	task.rush(); // 调用rush
	remains.add(task); // 添加到列表中
}

上面的代码,看似注释很多,但是却没有任何用处。因为它描述的是程序代码本身,哪怕程序代码写错了,注释也依旧对其描述一遍。

final List<Task> tasks = taskService.getSortedTask(BY_PRIORITY); //按优先级排序获取任务列表
final Task firstTask = tasks.get(0); // 排在第一位的是优先级最高的任务
task.done(); // 完成优先级最高的任务

final List<Task> remains = new ArrayList<>(9); // 剩余列表,用来保存最多1-9个任务(加上优先级最高的,就处理了前10个)
for (int i = 1; // 从第二个任务开始,第一个任务已经完成了
	i < 10 || i < task.size(); // 对1到9个任务进行迭代,如果(size)不到9个提前退出
	i ++) { // 继续获取下一个任务
	final Task task = task.get(i); // 准备操作的任务对象
	task.rush(); // 催办该任务
	remains.add(task); // 将该任务保留在剩余任务列表中
}

上面的代码注释,就描述的是业务逻辑,是处理过程算法。通过注释,可以核对实现的代码是否达到了目的,相当于一次代码review。

当然,上面的代码是示例,有一些违反开发规范的地方,如果想看比较好的满足规范的代码,也可以提供一个:

final List<Task> tasks = taskService.getSortedTask(BY_PRIORITY); //按优先级排序获取任务列表
final Task firstTask = tasks.get(FIRST_LIST_ITEM); // 排在第一位的是优先级最高的任务。此处使用的是确定的
task.done(); // 完成优先级最高的任务

final List<Task> remains = tasks.stream()
	.skip(1) // 忽略掉已经完成的第一个任务
	.limit(MAX_RUSH_TASK) // 限制最多到MAX_RUSH_TASK个任务(结合前面的skip不超过MAX_RUSH_TASK-1次迭代)
	.peek(Task::rush) // 催办该任务。此处是一个副作用代码
	.collect(Collectors.toList()); // 将处理后的任务收集到列表中

O Captain! My Captain!