如何写好一篇文档

背景

所有软件活动包括根本任务——打造由抽象软件实体构成的复杂概念结构,

次要任务——使用编程语言表达这些抽象实体,在空间和时间限制内将它们映射成机器语言。


编程人员所处理的工作内容,具有抽象性和不可见性,很难直观的将它表现给别人看。

而且,在编写软件的过程中,人们还会创造一个接一个的抽象概念。

相比使用编程语言将某一个概念实现而言,理解和传递这些抽象的概念才是根本难题。


我想开发者们都有这样的认识吧,实现一个给定的功能总是简单的,

而恰如其分的实现一个表述不清的功能,才是困难的。

开发人员的主要工作量,并不在编码环节,而是与外界交互。


从这个角度来看,在软件项目中,我并不认为具有自解释性的代码就足够了。

还得有必要的解释性文档。


传递知识

文档是一种知识传递的形式,它可以存档,可以重复利用。

如果编写者和阅读者决定使用文档的形式来传递知识,

那么我认为首先应该注意的是,“知识的诅咒”这种认知偏差。


知道某知识的人,下意识的是不了解不知道该知识的人的处境的。


代码的编写者,下意识的会认为,别人知道自己所做的种种假设,

接口的提供者,下意识的会认为,别人知道该如何调用它。

这就是最容易出现问题的环节,也是最消耗人力的环节。


编写文档,如果寄希望于阅读者来主动咨询自己,就写不出好文档,

而是应该把写文档看做提供服务,向阅读者传递必要的知识。


如果能把自己决策的动机写下来,就是一篇好的设计文档,

如果能把期望别人如何使用写下来,就是一份好的接口文档。

当然,有计划的人会先写文档。


必要的

有一些知识如果不出现在文档中,就会对阅读者造成困扰。


例如,好的文档应该首先交代背景知识,

如果文档一上来就开始写自己关心的内容,

读者就不会那么容易切换到合适的上下文中,

如果不交代背景,阅读者就不知道这篇文档到底想做什么。


还有,好的文档不应该把疑问抛给读者,

如果文档会引发疑问,那么这个疑问就很有可能不会被提出来,

而是由阅读者自主选择一个结论,显然这个结论很难与编写者的预期相符。


懂得站在对方角度考虑问题的编写者,迟早会摸索出这样的文档编写方式。

为了尽快的达到这一点,我们还需要一些技巧。


一个典型的技巧就是,如果觉得某些内容没什么必要,那也写出来。

因为阅读者可以忽略任何他想忽略的内容。

因此,对于专属名词,甚至上文已经提到过的概念,

也要不厌其烦的进行介绍,因为读者可能会略过它们。


还是那句话,

要以文档提供服务,而不是寄希望于读者主动咨询。

提高文档的可读性,并不影响读者在主动性方面对自身的严格要求。


不必要的

上文我们提到了,即使编写者认为没有什么必要的内容,也可以写到文档中。

因为读者可以忽略它们,而被忽略总比没有表述清楚要好。


可是,也并不是所有的内容都应该出现在文档中,

这可能会影响读者的整体思路,

对的,删除内容也一定是出自对读者的关心。


我想熟知面向对象编程的开发者们,一定知道信息隐藏这一技巧吧,

所谓信息隐藏,指的是对不必要的细节进行封装,对外表现出具有整体一致性的概念。

也只有对不必要的细节进行隐藏,才有办法表达更复杂的概念。


诚然,实现的细节是需要隐藏的,

但这也要建立在,对概念的外在解释足够好的基础上。

例如,如果你没有写明如何使用一份代码,哪怕写了很多私有函数,

也不算做好了信息隐藏,因为读者不得不去了解它的实现细节。


因此,代码不能算是文档,

它并不能说明我们为什么要这样解决问题,

它只是编码了实现给定功能的计算细节。


最后,如果我们已经做好了信息隐藏,那么被隐藏的细节,就不该暴露给读者,

这样有利于我们在更高的抽象层次上讨论问题。


总结

本文主要介绍了写好文档的思路和原则,

主要思路是,把编写文档看做提供主动的服务,而不是被动的咨询。


有一些知识需要广播出来,人们才可以有效的接收到,

这就是分享精神


如果期望别人主动,这就另当别论了,

我写了一篇文档给你看,目的是为了锻炼你的主动性,

我会觉得这一定是哪里有问题。


具有相关知识的开发者,有义务将这些知识传承下去,

如果别人因为信息缺失,浪费了时间,我会感到愧疚。

你呢?