软件设计的哲学: 第十五章 先写注释

许多开发人员将编写文档的工作推迟到开发过程的末尾,即编码和单元测试完成之后。这是产生低质量文档的最可靠的方法之一。编写注释的最佳时间是在过程的开始,即编写代码的时候。 首先编写注释使文档成为设计过程的一部分。这不仅产生了更好的文档,而且还产生了更好的设计,并使编写文档的过程更加愉快。

15.1 延迟的注释是糟糕的注释

我遇到的几乎所有开发人员都推迟了写注释的时间。当被问及为什么不更早地编写文档时,他们说代码仍然在变化。他们说,如果他们很早就编写文档,那么当代码发生变化时,他们就必须重写文档;最好等到代码稳定下来。然而,我怀疑还有另一个原因,那就是他们把文档看作是苦力工作;因此,他们尽可能地拖延。

不幸的是,这种方法有几个负面的后果。首先,延迟文档通常意味着根本不需要编写文档。一旦你开始拖延,很容易再拖延一点;毕竟,再过几周,代码将更加稳定。等到代码稳定下来的时候,已经有很多了,这意味着编写文档的任务已经变得非常艰巨,甚至没有吸引力了。从来没有合适的时间停下来几天,把所有遗漏的注释都补上,而且很容易让人觉得对项目来说最好的事情就是继续前进,修复bug或者编写下一个新特性。这将创建更多未归档的代码。

即使你有自律性回去写注释(不要欺骗你自己:你可能没有),注释也不会很好。在这个过程的这个时候,你已经在精神上离开了。在你的脑海里,这段代码已经完成了;你急于开始下一个项目。你知道写注释是正确的事情,但它没有乐趣。你只想尽快度过难关。因此,您可以快速地浏览代码,添加足够的注释以使其看起来令人满意。到目前为止,您已经有一段时间没有设计代码了,所以您对设计过程的记忆变得模糊了。您在编写注释时查看代码,因此注释重复了代码。即使您试图重构代码中不明显的设计思想,也会有您不记得的事情。因此,这些注释忽略了他们应该描述的一些最重要的事情。

15.2 先写注释

我用了一种不同的方法来写注释,我把注释写在最开始:

  1. 对于一个新类,我首先编写类接口注释。
  2. 接下来,我为最重要的公共方法编写接口注释和签名,但方法主体为空。
  3. 我对这些注释进行了一些迭代,直到基本结构感觉正确为止。
  4. 此时,我为类中最重要的类实例变量编写声明和注释。
  5. 最后,我填写方法的主体,根据需要添加实现注释。
  6. 在编写方法主体时,我通常会发现需要额外的方法和实例变量。对于每个新方法,我都在方法体之前写接口注释;对于实例变量,我在编写变量声明的同时填写注释。

代码完成后,注释也完成了。从来没有积压的不成文的注释。

先注释的方法有三个好处:

  • 首先,它产生了更好的注释。如果您在设计类时写下注释,那么关键的设计问题就会在您的脑海中浮现出来,所以很容易记录下来。
  • 最好在每个方法的主体之前编写接口注释,这样您就可以专注于方法的抽象和接口,而不会被实现分散注意力。
  • 在编码和测试过程中,您将注意到并修复注释中的问题。因此,注释在发展的过程中不断改进。

15.3 注释是一个设计工具

在开始时编写注释的第二个好处(也是最重要的一个好处)是改进了系统设计。注释提供了完全捕获抽象的唯一方法,好的抽象是好的系统设计的基础。如果您在开始时编写了描述抽象的注释,那么您可以在编写实现代码之前对它们进行检查和调优。要写出好的注释,您必须识别一个变量或一段代码的本质:这个东西最重要的方面是什么?在设计过程的早期就这样做是很重要的,否则你只是在破解代码。

注释就像是复杂煤矿中的金丝雀。如果一个方法或变量需要很长的注释,这是一个警告,说明您没有一个好的抽象。请记住,在第4章中,类应该是深入的:最好的类具有非常简单的接口,但是实现了强大的功能。判断接口复杂性的最佳方法是根据描述它的注释。如果方法的接口注释提供了使用该方法所需的所有信息,并且很短很简单,则表明该方法具有简单的interface。相反,如果没有长而复杂的注释就无法完整地描述一个方法,那么这个方法就有一个复杂的接口。您可以将方法的接口注释与实现进行比较,以了解该方法的深度:如果接口注释必须描述实现的所有主要特性,则该方法是肤浅的。同样的思想也适用于变量:如果需要很长的注释才能完整地描述一个变量,这是一个危险信号,表明您可能没有选择正确的变量分解。总的来说,编写注释的行为允许您尽早评估您的设计决策,这样您就可以发现并修复问题。

危险信号:难以描述

描述方法或变量的注释应该简单而完整。如果你发现很难写这样的注释,那就说明你所描述的东西的设计可能有问题。

当然,注释只有在完整和清晰的情况下才能很好地指示复杂性。如果您编写的方法接口注释没有提供调用该方法所需的所有信息,或者注释非常晦涩,难以理解,那么该注释就不能很好地度量方法的深度。

15.4 早期的注释很有趣

尽早写注释的第三个也是最后一个好处是,它让注释写作变得更有趣。对我来说,编程中最有趣的部分之一是新类的早期设计阶段,在这个阶段,我将充实类的抽象和结构。我的大多数注释都是在这个阶段写的,这些注释是我如何记录和测试我的设计决策的质量的。我正在寻找的设计,可以表达完整和明确的最少的语言。注释越简单,我对我的设计就感觉越好,所以找到简单的注释是我的骄傲。如果你是有策略地进行编程,你的主要目标是一个伟大的设计,而不是仅仅编写可以工作的代码,那么编写注释应该是有趣的,因为这是你识别最佳设计的方式。

15.5 早期的注释代价高昂吗?

现在,让我们重新讨论延迟注释的理由,即它避免了随着代码的发展而重新处理注释的成本。一个简单的粗略计算将表明,这并没有节省多少。首先,估计您在一起输入代码和注释所花费的开发时间,包括修改代码和注释的时间;这不太可能超过所有开发时间的10%。即使您的代码行总数的一半是注释,编写注释也不会占用您全部开发时间的5%。把注释拖到最后只会节省其中的一小部分,并不是很多。

首先编写注释将意味着在开始编写代码之前抽象将更加稳定。这可能会节省编码期间的时间。相反,如果您先编写代码,抽象可能会随着您的代码而发展,这将比先注释的方法需要更多的代码修订。当您考虑到所有这些因素时,首先编写注释可能会更快。

15.6 结论

如果你还没有尝试过先写注释,那就试试吧。坚持到习惯为止。然后考虑它如何影响您的注释质量、设计质量和软件开发的整体享受。在你尝试了一段时间后,让我知道你的经验是否与我的相匹配,为什么或为什么不。

posted @ 2019-12-26 10:04  peida  阅读(898)  评论(1编辑  收藏  举报