
1.2 传统文档存在的问题
文档是程序开发过程中的蓖麻油:主管们认为它会对程序员有益,而程序员却讨厌它!
——Gerald Weinberg,《程序开发心理学》
文档是一个无聊的话题。我不知道你怎么想,但就我以往的工作经历来说,文档一直是令我倍感挫败的重要原因。
当我想使用文档时,总是找不到需要的信息。我拿到的文档往往已经过时而且具有误导性,以至于我都不敢相信它。
为他人编写文档是一项无聊的任务,我宁愿写代码。其实,这件事可以不那么无聊。
我曾经多次看过、用过或者听说过一些处理文档的更好的方法,并试过了其中很多方法。我还收集了大量这种故事,在本书中你会读到其中一些。
良方自然是有的,但是你必须换一种新的思维来考虑编写文档这件事。有了这种思维方式以及随之而来的技术,编写文档可能就和写代码一样有趣了。
1.2.1 编写文档通常不太酷
当你听到文档这个词时会想到什么?你可能会给出如下答案。
- 它很无聊。
- 要写很多字。
- 意味着你要试着使用Microsoft Word,还不能忘了在哪里插入图片。
- 作为开发人员,我喜欢那些展现动作和行为的动态可执行文件。对我而言,文档是静止的,它就像一株枯死的植物,干枯不动。
- 本来以为它能帮上忙,结果它经常误导我。
- 编写文档很无聊。我宁愿写代码也不愿意编写文档(参见图1-1)!
图1-1 哦不,我还是写代码去吧
编写和维护文档需要大量时间。文档很快就会过时,通常不完整,而且不太好玩。文档是令人沮丧的一个原因。要带你领略这么无聊的一个话题,我感到很抱歉。
1.2.2 文档的缺陷
就像劣质酒的香味会快速消失一样,纸质文档的内容也会迅速失效,令你头痛不已。
——@gojkoadzic
传统文档存在许多缺陷和几种常见的反模式。反模式是指对重复出现问题的常见不良响应,应该避免。
下面描述了一些最常见的文档缺陷和反模式。你的项目中存在相关问题吗?
独立活动
即使在声称敏捷的软件开发项目中,决定构建内容、编码、测试和准备文档这几项工作之间也常常是相互独立的,如图1-2所示。
图1-2 软件开发项目中的独立活动
活动相互独立会导致大量浪费并丧失机会。基本上,所有的活动都会用到相同的知识,只是以不同的形式和工件来使用,并且可能伴有一定程度的重复。另外,在流程中,这些“相同”的知识可能会演进发展,从而导致不同活动中的知识内容不一致。
手工转录
需要编写文档时,团队成员会选择一些已完成工作的知识要素,然后手动将它们转化成适合目标受众的格式。基本上,这是一个为代码里已经写好的文档再写一份文档的过程,就像古登堡发明印刷机之前的抄写员一样(见图1-3)。
图1-3 手工转录
冗余知识
以上描述的转录过程导致了知识的重复:最终,你获得了反映真实情况的原始知识来源(通常是代码)和一堆以各种形式复制成的知识副本。不幸的是,当一个工件(例如代码)发生变化时,你很难记得要更新其他文档。于是,文档内容很快就过时了,留给你的是一份无法信任的不完整文档。这样的文档有什么用呢?
无聊的时间陷阱
管理层想为用户提供文档,还想用文档来解决团队中人员流动引发的问题。然而,开发人员讨厌编写文档。与写代码或使任务自动化相比,写文档一点意思也没有。对于开发人员来说,他们不太有兴趣编写一些会迅速过时且无法执行的无效文本。当开发人员写文档时,他们宁愿去处理真正在工作的软件。矛盾的是,当他们想复用第三方软件时,一般希望能有更多有用的文档。
技术文档工程师喜欢写文档,而且以此为生。但是,他们通常需要开发人员的协助才能获得编写文档所需的技术知识,而且经常做的仍是手工转录知识。这个过程令人沮丧,也浪费了大量宝贵的时间(见图1-4)。
图1-4 编写文档是一个时间陷阱
脑转储
因为编写文档不是一件有趣的事,而且我们只是因为必须要有文档才会这么做,所以编写文档时一般比较随意,不会考虑太多。结果是作者在编写文档时就做了脑转储,即想到什么就写什么(见图1-5)。问题在于,这种随机的脑转储对任何人都无益。
图1-5 编写文档时脑转储不一定有用
优美的图表
对于那些喜欢使用CASE(Computer-Assisted Software Engineering,计算机辅助软件工程)工具的人来说,这种反模式很常见。这些工具并不是为制作草图设计的。相反,它们鼓励使用各种布局和根据建模参考的验证来创建优美的大型图表。整个过程需要很长时间。即使这些工具能神奇地自动完成布局,创建一个简单的图表仍然需要很长时间。
迷恋符号
我们发现UML符号现在越来越不受欢迎了。UML在1997年被采用为标准,并在之后的十年里成为所有软件的通用符号,尽管它并不适用于所有情况。从那时起,再也没有其他符号被广泛地使用,而且即使不太合适,世界各地的团队仍会用一些UML符号来记录内容。当你只知道UML时,每一个图表看起来都像是它的标准图集之一。
不用符号
实际上,与迷恋符号完全相反的另一个极端已经相当普遍了。许多人完全无视UML,使用一些没人能理解的自定义符号绘制图表,并将诸如构建依赖项、数据流和部署之类的随机问题混为一谈。
信息墓地
企业知识管理解决方案是知识消亡的地方。看看这些:
- 企业wiki
- SharePoint
- 大型Microsoft Office文档
- 共享文件夹
- 搜索功能很差的工单系统和wiki
这些文档编写方法通常会失败,要么是因为通过它们很难找到正确的信息,要么是因为将信息保持最新状态需要大量工作,或者两者皆有。这些方法促进了只写文档(write-only documentation)或只写一次文档(write-once documentation)的形式。
在最近的一次Twitter交流中,著名软件开发商Tim Ottinger(@tottinge)问了这样一个问题。
产品类别:“文档墓地”——所有文档管理、wiki、SharePoint和团队空间是否注定失败?
James R. Holmes(@James_R_Holmes)回复如下。
我们的标准笑话是这样的:说“它在内网上”会引发“你刚刚是让我自己去__吗?”的回应。
(注意:因为原话用了粗俗的语句,所以做了编辑。你懂的。)
误导性的帮助
只要文档不能严格保持最新,就会产生一定的误导性,如图1-6所示。虽然文档看起来有用,但事实上是错误的。因此,这些文档可能读起来有意思,但是辨别哪些内容仍然正确以及哪些内容已经不再正确会造成额外的认知负担。
图1-6 当文档无法正确指导用户时,它就是有害的
总有更重要的事
编写高质量的文档需要很多时间,而维护它甚至需要更长时间。如果一个人时间紧迫,他就会经常略过文档任务,或者快速、粗糙地完成文档。
1.2.3 敏捷宣言与文档
《敏捷宣言》是由一群软件从业者于2001年撰写的。在这份宣言中,他们列出了自己认为有价值的东西,包括:
- 个体和互动高于流程和工具
- 工作的软件高于详尽的文档
- 客户合作高于合同谈判
- 响应变化高于遵循计划
第二个偏好“工作的软件高于详尽的文档”常常被误解。很多人认为《敏捷宣言》完全无视文档。实际上,《敏捷宣言》并没有说“不写文档”,它描述的只是一个偏好。用宣言作者的话说:“我们接受文档,但不是浪费大量纸张印成一堆从不维护也基本不用的大部头。”但是,随着敏捷方法在大型公司中成为主流,这种对文档的误解仍然存在,而且很多人忽略了文档。
但是,我最近发现客户和同事经常因为文档缺失而感到挫败,而且这种挫败感越来越严重。2013年,在瑞典Öredev会议上首次提到活文档时,我惊讶地发现很多人对这个概念很感兴趣。
1.2.4 是时候开启文档2.0了
传统文档是有缺陷的,但是我们现在对文档了解得更多了。自20世纪90年代末以来,诸如整洁的代码、测试驱动开发(TDD)、行为驱动开发(BDD)、领域驱动设计(DDD)和持续交付之类的实践越来越流行。这些实践改变了我们关于软件交付的思考方式。
对于TDD,测试一开始被视作需求说明。对于DDD,我们可以识别代码和业务领域的建模,从而打破模型与代码相隔离的传统。这么做的一个结果是,我们希望代码能够描述相关领域完整的故事。BDD借用了业务语言的概念,并在工具支持下使它更为直白。最后,持续交付表明,几年前我们认为在没有特殊原因的情况下每天交付几次的想法很荒谬,而这实际上却是可能实现的,而且如果遵循建议的做法,这甚至是可取的。
当前正在发生的另一件趣事是由时间的影响引起的:尽管文学式编程(literate programming)或HyperCard这样的旧概念并没有成为主流,但是它们仍然缓慢而悄无声息地产生了影响,尤其是在F#和Clojure等较新的编程语言社区里,这些旧概念焕发了新生。
现在,我们终于可以期待有这样一种文档编写方法:它实用,能使文档内容永远保持最新,成本低,并能让编写文档变得有趣。我们意识到了传统文档编写方法存在的所有问题,也认识到了文档的必要性。本书就其他方法如何更高效地满足文档需求做了探讨并提供了指导。但是首先,让我们探讨一下文档到底是什么。