科普文章
四十年软件工程故事
时间:2009-09-02

  2008年5月14-16日,在德国迷人的小镇Garmisch,举办了软件工程四十年纪念会议,Peter Naur、Brian Randell、M. Douglas McIlroy、Albert Endres、Luigi Dadda等40年前软件工程会议的关键人物重聚旧地。

  40年前的1968年,正是在此地举行的NATO(北约)科技委员会会议上,“软件工程”作为正式的术语被确定下来,标志着一个新学科的开始。 Peter Naur和Brian Randell主编的会议报告中这样写道:“我们特意选择‘软件工程’这个颇具争议性的词,是为了暗示这样一种意见:软件的生产有必要建立在某些理论基础和实践指导之上——在工程学的某些成效卓著的分支中,这些理论基础和实践指导早已成为了一种传统。”

  软件工程这个学科还很年轻,Peter Naur和Brian Randell今天依然健在。作为著名的编程语言归约BNF范式中的N,Peter Naur因设计和定义了ALGOL 60而在2005年获得图灵奖。因IBM System360的工作于1999年获得图灵奖的Fred Brooks在《人月神话》的结尾比较了化学工程和软件工程。他认为:软件系统可能是人类所创造的最错综复杂的事物,软件工程还很年轻,需要继续探索和尝试。

  这四十年的过程就是探索和尝试的过程,让我们来细细品味其中的科学精神之美。

软件工程是什么

  软件工程的定义有很多版本,比较权威的是IEEE给出的定义:(1)将系统化的、规范的、可量化的方法应用于软件的开发、运行和维护,即,将工程应用于软件。(2)在(1)中所述方法的研究。

  所以,软件工程远没有想象中那么高大神秘,它研究的就是我们日常开发软件的工作方式。“程序员”这三个字本就属于软件工程的范围。

  关于软件工程和计算机科学的区别,Fred Brooks说:A scientist builds in order to learn; an engineer learns in order to build. 更详细的可以看看David Parnas的“Software Engineering Programs Are Not Computer Science Programs”和Steve McConnell所著“Professional Software Development”的第4章。或者对照一下图灵奖获得者:软件工程领域的David Parnas、Frederick P. Brooks和计算机科学领域的Donald E. Knuth、《程序员》上期介绍的YAO。

  软件是为人开发的,软件是由人开发的。正是因为人的心理难以捉摸,人的大脑处理复杂性时速度和容量的局限,我们才需要过程来规范人的行为,需要方法来帮助人脑面对复杂性,需要工具来贯彻这些过程和方法。所以,软件工程的知识体系分为以下几层。我们按照这个金字塔结构,逐层回顾四十年来的历史。

过程

  一开始,软件团队是没有过程的,甚至没有团队概念。没有需求规格说明,没有设计,程序员在大脑中直接将代码思考出来,拼凑到一起,交给客户使用。客户如果有要求,再修改代码,如此反复。这种“编码-修改”做法对于小程序可以应付,当程序规模变得复杂时,付出的代价就很大了。

瀑布

  “软件工程”概念的提出,促进了需求、分析、设计、实现、维护等软件生命周期概念的成熟。瀑布模型是最早的软件过程模型,从名字“瀑布”可以看出,通常人们认为瀑布模型中的各个步骤是一条线完成的。实际上在Winston W. Royce1970年的经典论文“Managing the Development of Large Software Systems”中有反馈的过程(见图3),作者本人也并不提倡以顺序模型作为团队的过程模型,另外,Royce并没有在论文中把他的过程模型叫做“瀑布 ”,只是后来其他人这么叫了。很多团队使用时是按照线性的方式使用的,这是一种误解。

  这里要提一下,瀑布模型的提出者Winston W. Royce(已于1995年去世)有时被简写为W. Royce,所以经常会引起误会,把他当成Walker Royce,后者是软件项目管理专家,曾任Rational软件公司副总裁,著有《Software Project Management: A Unified Framework》一书。

增量和迭代

  使用瀑布模型,可以运行的产品很迟才能看到,这就潜伏了巨大的风险:很可能,集成之日也就是爆炸之日。为了提早获得可以运行的版本,可以先实现一些功能,再实现一些功能……每个增量交付一个可以运行的版本。

  增量开发显著降低了风险,而且还因可运行产品的出现大大提升了士气。最有名的实践应该是Microsoft在1989年就开始使用的Daily Build(每日构建),被称为项目的“心跳”。当然,增量开发不一定意味着每日构建,如Fred Brooks所述,Bell Northern Research是“每周构建”。

  增量经常和迭代连在一起说,不过两者是有区别的。增量是逐块建造的概念,迭代是反复求精的概念。二者不一定要绑在一起使用,但很明显,结合这两种方式是一种有效的做法。现在很多过程所说的迭代开发,默认的意思就是增量&迭代。Jeff Patton最近用两幅图表达了增量和迭代(http://www.agileproductdesign.com/blog/dont_know_what_i_want.html)。