所以在敏捷(Agile)的词汇表里已经没有详细设计这个词汇了,取而代之的是“够用设计”,是所谓的Not less not more, just enough。那么在敏捷这种短迭代周期,快速反馈体系中,是否还有必要编写一份用自然语言或图表展示的详细设计文档呢?Jack W.Reecves在他的论文《什么是软件设计?》中提出了“源代码是设计文档”的观点,Jack说得设计文档和我本文提到的设计文档还不是同一个概念,我把他的观点引用在这里主要是为了和另一个观点做对比。Jack认为,“任何工程活动的终目标都是某些类型的文档。当设计工作完成时,设计文档被转交给制造团队。该团队是一个和设计团队完全不同的群体,并且其技能也和设计团队完全不同”,由此看来,如果源代码不是文档,那么软件开发人员不能被称为是工程师了,他们和建筑工地上的工人一样,只是一群Builder。是否可以用源代码代替任何用自然语言描述的文档呢?我看还不太可行,源代码相对于自然语言来说过于晦涩,只有开发人员能够读懂(即便是开发人员,也不是所有人都能理解所有代码),显然制约了源代码作为文档的用途。不是有人在研究用自然语言编程序吗,如果这样的类似自然语言的源代码作为文档,倒是很合适。

 上文提到,有一个与之对比的观点,那是用测试代码代替源代码作为设计文档,但是前提条件是:使用TDD作为开发模式。很显然,源代码产生以后做单元测试用的测试代码已经失去了作为设计文档的前提,那是每次迭代的设计文档必须早于或不晚于本次迭代的源代码产生出来。因为作为单元测试的测试代码是为已经存在的源代码量身定做的,并且已经受到这些代码的思维定势影响,失去了“设计”的意义。做为测试先行的TDD本身是一个分析、设计、实现的过程,而测试代码又是这个过程的产物,测试代码理所当然的是设计文档了。加之TDD要求在编写任何代码之前要先完成测试用例,这是说任何新代码(新加的模块)都有配套的测试代码,自然而然的,测试代码成为了新代码的描述文档,其中包含了如何建立使用新模块以及期望达到什么样的效果,而这正式设计文档的主要功能。源代码不适合取代自然语言的文档,因为源代码过于功能细化,逻辑纷繁复杂,分支和跳转加剧了理解代码的困难,缺乏对整个模块的宏观表达能力。与源代码相比,测试代码显然“单纯”很多,测试代码侧重于使用源代码,通常可以用作源代码的一份sample,所以它对整个模块的宏观表达能力要强于源代码。另外,测试代码通常是线性结构,比较容易看懂,从可理解性上看,测试代码比源代码更接近自然语言,因此测试代码比源代码更适合作为软件的设计文档。
  

那么测试代码是否可以完全取代自然语言形式的设计文档呢?我看还不行,原因有三:

其一,测试代码虽然比源代码容易理解,但它仍然是代码,不是所有人都能理解的;

其二,测试代码的宏观表达能力还是不如自然语言或图表;

其三,很多人习惯看文字而不是看代码,彻底改变人的习惯很难。

所以在TDD开发过程中,比较好的形式是自然语言的文档和测试代码相结合,用自然语言的文档做一个够用的设计行了,这个设计只要详细到模块关系这一级别足够了,各个模块的详细设计由测试代码充当。

不管是“源代码是文档”的观点还是“测试代码是文档”的观点,目的都只有一个,那是消除那些浪费人力物力做出来的、没用的、总是散发着“腐败”味道的东西。