> 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/ch18/18.1-shi-dai-ma-geng-yi-yu-li-jie-de-dong-xi.md).

# 18.1 使代码更易于理解的东西

使代码易于理解的两个最重要的技术已经在前面的章节中讨论过了。第一个是选择好的名称（第14章）。精确而有意义的名称可以阐明代码的行为，减少对文档的需求。如果名称模糊不清，那么读者将不得不通读代码，以推断出被命名实体的含义；这既费时又容易出错。第二个技巧是一致性（第17章）。如果类似的事情总是以类似的方式完成，那么读者就可以识别出他们以前见过的模式，并立即得出（安全的）结论，而无需详细分析代码。

下面是一些其他的通用技术，可以使代码更加明显。

**明智地使用空白。**&#x4EE3;码的格式化方式可以影响它的易懂程度。考虑一下下面的参数文档，其中的空白已经被挤掉了：

```java
/** 
 * ...
 * @param numThreads The number of threads that this manager should
 * spin up in order to manage ongoing connections. The MessageManager
 * spins up at least one thread for every open connection, so this
 * should be at least equal to the number of connections you expect
 * to be open at once. This should be a multiple of that number if
 * you expect to send a lot of messages in a short amount of time.
 * @param handler Used as a callback in order to handle incoming
 * messages on this MessageManager's open connections. See
 * {@code MessageHandler} and {@code handleMessage} for details.
 */
```

很难看到一个参数的文档在哪里结束，下一个参数在哪里开始。甚至不知道有多少个参数，或者它们的名字是什么。如果增加一点空白，结构就会突然变得清晰，文档也会更容易浏览：

```java
/** 
* @param numThreads
*          The number of threads that this manager should spin up in
*          order to manage ongoing connections. The MessageManager spins
*          up at least one thread for every open connection, so this
*          should be at least equal to the number of connections you
*          expect to be open at once. This should be a multiple of that
*          number if you expect to send a lot of messages in a short
*          amount of time.
* @param handler
*          Used as a callback in order to handle incoming messages on
*          this MessageManager's open connections. See
*          {@code MessageHandler} and {@code handleMessage} for details.
*/
```

空行对于分隔一个方法中的主要代码块也很有用，比如下面的例子。

```cpp
void* Buffer::allocAux(size_t numBytes) 
{
    // Round up the length to a multiple of 8 bytes, to ensure alignment.
    uint32_t numBytes32 = (downCast<uint32_t>(numBytes) + 7) & ~0x7; 
    assert(numBytes32 != 0);
    
    // If there is enough memory at firstAvailable, use that. Work down
    // from the top, because this memory is guaranteed to be aligned
    // (memory at the bottom may have been used for variable-size chunks).
    if (availableLength >= numBytes32) {
       availableLength -= numBytes32;
       return firstAvailable + availableLength;
    }
    
    // Next, see if there is extra space at the end of the last chunk.
    if (extraAppendBytes >= numBytes32) {
       extraAppendBytes -= numBytes32;
       return lastChunk->data + lastChunk->length + extraAppendBytes;
    }
    
    // Must create a new space allocation; allocate space within it.
    uint32_t allocatedLength;
    firstAvailable = getNewAllocation(numBytes32, &allocatedLength);
    availableLength = allocatedLength numBytes32;
    return firstAvailable + availableLength;
}
```

如果每个空行后的第一行是描述下一个代码块的注释，这种方法就特别有效：空行使注释更加明显。

语句中的空白有助于阐明语句的结构。比较以下两条语句，其中一条有空白，一条没有。

```cpp
for(int pass=1;pass>=0&&!empty;pass--) {

for (int pass = 1; pass >= 0 && !empty; pass--) {
```

**注释。**&#x6709;时无法避免不易于理解的代码。当这种情况发生时，重要的是使用注释来弥补所缺的信息。要做好这一点，你必须把自己放在读者的位置上，弄清楚什么东西可能会使他们感到困惑，什么信息可以消除这种困惑。下一节将介绍几个例子。
