API对设计流程的影响
Seibel:你设计软件的流程是什么样的?打开Emacs就开始写代码,然后改来改去直到程序写好?还是坐到沙发上拿着一打纸先列个提纲?
Bloch:很多年前,我在OOPSLA(译者注:面向对象编程、系统、语言和应用国际研讨会。)上作了一个演讲,题目是“如何设计一个好的API,以及这为什么很重要”。网上可以找到这个演讲的几个版本。它很好地解释了我的设计流程。
最重要的是了解你到底要设计什么,也就是你要解决的是什么问题。需求分析的重要性怎么强调也不过分。有人认为:“噢,需求分析呀。跑到顾客那边问问他需要什么。得到客户的答案不就成了嘛。”
事实绝非如此。这不仅是一个协商的过程,而且是一个理解的过程。许多顾客不会告诉你问题,而会告诉你一个解决方案。例如,顾客可能会说:“我需要你给这个系统加上以下17个特性。”那么你必须问:“为什么?你想用这个系统做什么?你期望它怎么发展?”等等。你要来来回回好几次,直到弄明白顾客真正需要软件去做的所有事情。这些就是用例。
这个阶段最重要的事情就是提出好的用例。一旦有了用例,你就有了用来比较所有备选解决方案优劣的基准。你可以花大量的时间去改进用例,因为一旦用例错了,你就彻底失败了,所有后续的流程都会徒劳无功。
我见过这样的事。有人找来一帮聪明人,还没搞清到底要做个什么样的系统,就开工了。辛苦地工作了6个月,写出来247页的系统规范文件。这是最糟糕的情况。因为6个月后他们精确制定出来的系统可能毫无用处。他们往往会说:“我们已经投资了那么多,制定出来规范文件,我们必须把这个系统做出来。”所以他们创造了一个没有任何用处的系统,这个系统也从未投入使用过。多恐怖啊。如果没有用例就做好了软件,那么当你试图做点非常简单的操作时就会发现:“哦,我的天,像选择一个XML文档并打印这么简单的事情,需要这么多的代码啊。”这是很恐怖的。
所以先获取这些用例,然后编写骨架API。骨架API应该很短很短,也就一页纸的内容吧,一般正好是一页,无需非常精确。你要声明包、类和方法,如果还不清楚他们应该是什么样的话,可以放一句话的描述。不过这不是产品发布要求的那种质量文档。
中心思想就是在这个阶段保持敏捷,逐步完善API,使其满足用例,为原始的API添加代码,看是否可以满足需求。真是不可思议,很多事情事后看真是太浅显了,但设计API的时候,甚至是构思用例时,你还是会犯各种错误。用代码实现用例时你会说:“哦,我的天,全都错了。类太多了。这些可以合并,这些需要拆开。”或者类似这样的话。好在API文档只有一页长,改起来也很容易。
你对API越来越有信心,代码也就越写越长。但是,核心原则是,先写使用API的代码,然后再写实现它们的代码。因为,如果实现代码被废弃,之前的工作就都白做了。事实上,应该在给出设计规范前写API的代码,否则你可能把时间浪费在给最后完全不需要的东西设计规范上。这就是我设计软件的方法。