> For the complete documentation index, see [llms.txt](https://placeboy.gitbook.io/a-philosophy-of-software-design/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://placeboy.gitbook.io/a-philosophy-of-software-design/di-shi-san-zhang-zhu-shi-ying-gai-miao-shu-na-xie-zai-dai-ma-zhong-bu-ming-xian-de-dong-xi/13.3-geng-di-ceng-ci-de-zhu-shi-zeng-jia-le-jing-que-xing.md).

# 13.3 更低层次的注释增加了精确性

现在你知道什么是不应该做的了，让我们来讨论一下你应该在注释中添加什么信息。**注释通过提供（与代码）不同层次的信息来充实代码。**&#x4E00;些注释提供了比代码更低层、更详细的信息；这些注释通过阐明代码的确切含义来提高精确性（*precision*）。其他注释提供了比代码更高层、更抽象的信息；这些注释提供了直觉（*intuition*），如代码背后的推理，或更简单、更抽象的思考代码的方式。与代码处于同一层次的注释很可能会重复代码的内容。本节将详细讨论更低层次的方法，下一节将讨论更高层次的方法。

在注释变量声明（如类的实例变量、方法参数和返回值）时，精确性是最有用的。变量声明中的名称和类型通常不是很精确。注释可以填补缺失的细节，比如：

* 这个变量的单位是什么？
* 边界条件有没有被包含进去？
* 如果允许空值，它意味着什么？
* 如果一个变量引用了一个最终必须被释放或关闭的资源，谁负责释放或关闭它？
* 变量（不变量）是否存在某些始终为真的属性，例如“此列表始终包含至少一个条目”？

这些信息中的一部分有可能通过检查所有使用该变量的代码而被发现。然而，这样做既费时又容易出错；声明的注释应该足够清晰和完整，使这样的做法成为不必要的。当我说声明的注释应该描述那些在代码中不明显的东西时，“代码”是指注释旁边的代码（声明），而不是“应用程序中的所有代码”。

变量注释最常见的问题是注释太模糊了。下面是两个注释不够精确的例子：

```cpp
// Current offset in resp Buffer 
uint32_t offset;
```

```cpp
// Contains all line-widths inside the document and 
// number of appearances.
private TreeMap<Integer, Integer> lineWidths;
```

在第一个例子中，我们不清楚“当前”是什么意思。 在第二个例子中，我们不清楚 TreeMap 中的键是行宽，值是出现次数。 另外，宽度是以像素还是字符来衡量的？ 以下修改后的注释提供了更多详细信息：

```cpp
// Position in this buffer of the first object that hasn't
// been returned to the client. 
uint32_t offset;
```

```cpp
// Holds statistics about line lengths of the form <length, count> 
// where length is the number of characters in a line (including 
// the newline), and count is the number of lines with 
// exactly that many characters. If there are no lines with 
// a particular length, then there is no entry for that length. 
private TreeMap<Integer, Integer> numLinesWithLength;
```

第二个声明使用了一个较长的名称，传达了更多信息。它还将“宽度”改为“长度”，因为这个术语更容易使人们认为单位是字符而不是像素。请注意，第二个注释不仅记录了每个条目的细节，而且还记录了如果缺少某个条目意味着什么。

当记录一个变量时，要考虑名词（*noun*），而不是动词（*verb*）。C换句话说，重点是变量代表什么，而不是如何操作它。考虑一下下面的注释：

```cpp
/* FOLLOWER VARIABLE: indicator variable that allows the Receiver and the 
 * PeriodicTasks thread to communicate about whether a heartbeat has been 
 * received within the follower's election timeout window.
 * Toggled to TRUE when a valid heartbeat is received.
 * Toggled to FALSE when the election timeout window is reset. */ 
private boolean receivedValidHeartbeat;
```

这个文档描述了这个变量是如何被类中的几段代码修改的。如果注释描述了变量所代表的内容，而不是照搬代码结构，那么注释将既更简短且更有用：

```cpp
/* True means that a heartbeat has been received since the last time 
 * the election timer was reset. Used for communication between the 
 * Receiver and PeriodicTasks threads. */ 
private boolean receivedValidHeartbeat;
```

根据此文档，很容易推断该变量必须在收到心跳时设置为 true，而在重置选举计时器时必须设置为 false。
