追本溯源是人类的天性。当面对问题时,人们都会问,为什么这样做不行?为什么那样做就行?谈及软件研发过程中的问题和改善措施,需要首先分析其问题的本质,究竟是什么原因造成了软件研发过程的众多问题。这样我们才能说服自己,也说服别人,从根本上做些改变。
在分析软件研发特点之前,让我们首先讨论一下人类另外两大类主要活动:一类是物质财富生产,另一类是科学技术研究。物质生产的特点是大部分活动日复一日的重复性,比如我们生产汽车,制造电视,耕种庄稼等等。虽然每一次生产周期可能有些过程改进、技术进步,但是其本质上的创新还是很少。而科学技术研究,特别是基础研究,其突出的特点就是创新性。如相对论,宇宙起源,黑洞理论等等。开创性是这类活动的最大特点。比较这两类活动有很多角度,单从过程控制来看,生产控制远比基础研究控制来的容易,现代化生产管理的宗旨就是设法以最高的效率、最高的质量,稳定地大规模生产产品。我们今天极大丰富的物质生活,很大程度上依赖于各行各业行之有效的重复的物质生产过程。而基础研究,因其天然的不确定性和巨大的风险性,虽然也有一定的规律可循,但是如果试图对基础研究过程进行完全地精确控制却仍是十分困难,或者根本不可能。很难想象我们能对霍金先生目前的黑洞研究提出一个有明确研究计划和日程安排的黑洞理论2.0项目。
作为信息时代重要组成部分的软件,作为后来者,从其萌芽到今天发展成为一个巨大的产业并彻底改变了人们日常生活和工作方式,它至始至终都受到既有理论和工作方法的影响。最初,软件研发基本没有过程控制,软件研发被看做是一群“艺术家”的活动,基本没有管理的痕迹。目前在一些小公司还存在这种作坊式的软件研发模式,它的问题就是软件研发的质量进度高度不可控、不可知。随着软件规模的日益扩大,所谓的软件危机爆发。人们为了加强过程控制,求助于生产领域的既有经验,提出了所谓的瀑布式软件研发流程。在我看来,瀑布式流程基本上是工厂产品生产过程在软件研发活动中的模仿。其基本思路是,类似于工厂产品生产流程,把整个软件研发生命周期划分成前后衔接、日期任务明确定义的若干阶段(就像工厂生产产品的各个工序)、并对每次阶段跳转进行严格控制(就像工厂生产产品时每个工序的质量检验)。人们寄希望于这个结构定义清晰,责任划分明确的软件研发模式,把以前混乱的软件研发过程改造好,使之可以像工厂生产电视、汽车那样,质量稳定地、进度可控地进行软件研发。虽然目前在许多软件公司还能看到这种瀑布模型的影子,但是无数的实践证明,这种仿效工厂产品生产流程的软件研发模型,在大规模、逻辑复杂、市场状况瞬息万变的现代软件研发环境中,却屡屡难以奏效。
瀑布模型最根本的问题在于,虽然它定义了严格的阶段跳转验收标准,却没有回答一旦在一阶段末期,发现该阶段验收指标没有达到,或者在一个阶段发现前面阶段的错误时,如何回溯,如何可控地解决问题。瀑布模型缺乏有效的弥补机制,它往往是在项目后期才发现软件研发的进度和质量远远未达预期。那时,除了项目延期、增加投入这些不得已而为之的选择之外,不再有更早发现问题的机制和优雅的补救措施。所以,我经常说,瀑布模型基本上就是一锤子买卖或者赌博式的研发方式,凭运气,要么成功,要么成仁。
那为什么软件研发即不能被当作纯粹基础理论研究来对待,也不能当作物质产品生产来对待呢?因为软件研发,究其本质,是一种既有一定创新性、又有成本、资源和市场限制的、介于科学研究和物质产品生产之间的一种特殊的生产活动。承认其创新性,就要求以一种灵活的方式来对待;认识其投入和日程限制的商业性,又要求对其过程进行严密有效的监控,以最高可能的稳定性,规模化地生产软件产品,达到各软件研发机构合理的投入产出预期。
下面较详细地阐述软件研发的几大特点:
软件研发是一定程度上的开创性、创新性活动
软件研发有时具有一定的重复性,但是完全重复的劳动却极少。绝大部分软件研发活动是做新功能。因为如果某功能以前已经做过了,完全可以直接复用原来的模块或者把原来模块适当改造成可复用的模块,从而避免重复劳动。因为软件是软的。这点是软件研发跟物理产品重复生产最大的区别。物理产品生产,比如制造汽车,虽然每一辆汽车完全相同,却也要经历一个全新的花费相当成本的生产过程。而软件产品的复制,如软件安装程序的复制、传播,相对于软件研发本身来说,基本可以忽略其工作量。所以人们常说软件设计开发即是生产。
软件需求经常是不完整的或者经常发生变化的
软件之所以叫做软件,就是其软的特性。由于软,人们经常很难在研发之初提出或得到完整正确的、符合最终用户需要的需求全集。用户经常不擅于表达对软件功能的需求,往往等到看到实在的软件产品时,才意识到某些功能不完整或者有更好的想法。也是由于软件软的特点,很难限制用户对软件功能提出修改的冲动。这方面也是软件研发和一般产品生产很大的区别。比如盖一幢楼,盖好后,其实用户也有可能对楼房设计有新的更好的想法,但是改造已经盖好的楼房却十分困难或者根本不可能,这一定程度上也就限制了用户天马行空的改造动机。而软件却没有这么幸运。
对软件需求的理解,最终用户和研发团队比较容易不吻合
软件由于其前期不可触摸性,再加上最终用户和研发人员的知识背景,语言习惯、表达方式上的不同,很容易造成对同一个功能理解上的差异。即便有完备的文档帮助大家理解、澄清需求,甚至双方都签字画押,但自然语言毕竟不是程序代码,而且自然语言本身也可能有二意性,因此功能需求误解也是软件研发过程中比较容易发生的事情。
软件研发过程中,进度和质量比较难以正确衡量、跟踪
软件由于其设计和代码的不容易直观接触性,在较长的研发过程中,极有可能进入一种神秘的不可知的状态。不同于生产线上的产品,生产线上每个工序每个环节都可能定义出明确的操作规范和质量进度控制指标。而软件研发过程中的进度和质量控制,如果没有真正有效的方法,很容易流于形式。我曾经多次见过简单无效的进度跟踪方法,比如进入写代码阶段后,我们经常简单地让程序员定期地报告其完成百分比,10%,20%...100%。这样的百分数很难真实反映软件研发进度。我们往往在听到每个程序员都报告百分之百完成开发任务,想当然认为可以向下一阶段系统测试前进时,才发现那时的软件质量根本不够进行系统测试。很多基本的功能都无法运行。系统测试随即陷入无穷无尽的找bug修改bug再找bug无限循环的状态。软件一旦进入这样的状态,严重的日程延期,严重的超预期投入,甚至于最终项目被取消几乎成了不可避免的结局。
软件研发是商业行为,有时效性和投入产出的要求和限制
市场经济条件下,软件研发基本都是公司行为。作为商业软件公司,软件研发活动必定要符合商业活动的基本要求,软件公司才能在市场上生存。因此软件的发布时间(周期)、投入产出比就成了衡量软件研发是否成功的重要指标。在这样的商业环境下,用对待纯粹基础研究的态度对待软件研发显然不适合。
本章首先通过对比软件研发与物质产品生产、基础研究之间的不同之处,分析了软件研发的特点,让我们认识到,要改善和提高软件研发的生产率和过程控制,就必须采用适应软件研发特点的新思维和新方法。为后续章节讨论具体改善措施做了思想理论铺垫。