先来看工程,工程的第一个特点是可预见性。也就是说,在工程还没有开始以前,已经在人们心目中有了一个具体的形象和标准,工程的目标则是去实现这个已经被设计好的东西。我们知道建筑施是工队典型的劳动密集型产业,施工队按照设计好的图纸施工(用户是房产商),按照制订好的标准验收,这个标准可以定得非常细致,每堵墙,每道梁,每扇窗都可以细微到毫米。而技术密集型的特点则是不可预见性,比如达芬奇在画蒙娜丽莎以前,绝对没有人告诉他眼睛应该画多大,头发应该画多长。
软件粗看起来很类似做房子,前期用户提需求,建立软件规格标准,然后可以根据软件规格来做。但很少有软件项目最后做出来的样子是完全和当初写的规格说明书上一模一样的。大多数用户在开发过程中或使用过程中会新提出很多更改的要求,甚至把软件改得面目全非。这是软件工程学很不愿意面对的一种事实,因为工程学的理论基础是目标的可清晰预见性,而在工程中发生不可预见的变化成本非常巨大。因此传统的软件工程倡导前期做大量细致的需求和分析工作,企图减少中途发生变化的可能。
而敏捷开发则是承认软件的不可预见性,倡导努力提高应对变化的能力来降低甚至消除变化所带来的成本。不过这是另外一个话题,以后可以专门介绍。
工程的第二个特点是可控性高。几十年前做一栋房子的成本和现在比起来,除掉货币的升贬值并没有太大的变化。而较好施工队和较差的施工队比起来,成产率也不会相差很多。因此做栋房子的成本一般可以估算得很精确。但是软件不一样,现在一个人化一个月时间就可以用ASP.NET写一个电子商务网站,如果用十几年前的技术,比如汇编语言,投入几百个人都写不出来。所以软件的成本估算很难精确估算,如果几天前还计划要花好几个人几个月的时间来实现个比较复杂的功能,可能几天后就突然在某个网站上下载到了已经完美实现这个功能的源代码。而因为一个关键性的技术无法实现,导致整个项目全部被否决的情况也非常常见。
工程的第三个特点是强调过程管理,忽略个人因素。施工队上的某个工人辞职了对整个工程的进展几乎没有什么影响,没有哪个人是关键人物,随便换谁都无所谓,哪怕全部人都走掉,完全重新换一批也没什么影响。但是软件不一样,如果核心的开发人员离职,对项目有非常严重的影响。如果整个开发团队走掉,对项目来说绝对是致命的。
软件工程学一直把软件开发划分为两个过程,设计过程和实施过程。这是从传统工程行业照搬过来的,撰写软件规格文档看作是设计过程,由专门的系统分析人员来完成,类似建筑设计师,只需要写设计文档。而把编码看做是实施过程,由专门编码人员来完成,类似工程施工队。
软件工程设计师企图让软件设计文档像建筑物的设计图纸和说明一样,可以清晰描述软件的每一个具体的细节规格。其实这是一个可笑的悖论。如果文档有能力描述每个功能的最细节业务逻辑的需求的话,其实就是源代码(因为自然语言存在二义性,因此不存在描述严密逻辑的可能。而唯一能精确描述业务逻辑需求的就是源代码,所以描述精确的业务需求的过程其实就是写代码)。
而建筑设计师的源代码就是标准设计严密的图纸,这个图纸是逻辑精确严密的,可以交给任何一个正规施工队来正确执行的,设计师和施工队可以不需要任何交流。同样,程序员写的代码也是逻辑精确严密的,可以交给任何一台电脑来正确执行的,程序员和电脑也不需要开会谈话。
你能想象一个不会画标准建筑设计图纸的建筑设计师吗?同样,我也完全无法想象一个不会写代码的软件设计师。
所以,建筑设计师在软件开发中就是程序员,而建筑施工队在软件开发中就是计算机。
企图将程序员当做施工队来进行管理是不适合的,传统行业中对设计师的管理可能更加值得软件企业的学习。
话说回来,软件工程学也发展了好多年,难道完全是错误的吗?没有一点应用价值吗?我的经验告诉我,存在必然是合理的。软件工程也有他的适用范围,但是我们要加以分析才能利用,首先要看对我们自己是否合适。
我认为软件工程的确对某些项目是适合的,但是项目要满足以下四个特点:
◆ 软件的规格目标是非常清晰确定的,开发过程中几乎不会发生更改的。
◆ 实施过程中采用的所有技术都是非常熟悉的。
◆ 对稳定性的需求大大超过开发效率的。
◆ 可以不考虑成本的。
有没有这样的项目?有,航天飞机的自动控制系统软件就是满足这样要求的工程。事实上,软件工程诞生的背景也正是美国军方的一些大型项目。写软件工程的一些大师级人物也正是这些项目的领导人。
我们是不考虑事物的变化,采用刻舟求剑的方式来蒙蔽自己的双眼?还是仔细考察自己的特点,变通的选择真正适合自己的东西?