技术开发 频道

传统软件工程最后的经典

【IT168 技术文章】

    Square-Cal 3.0 版要在2.0 版上市后的10 个月发布,项目经理Mickey 与上司Kim 讨论后决定:他们将为项目组成员提供私人办公室、最新型的计算机以及免费的碳酸饮料,并且要求开发者在前8 个月按照预先设计好的接口各自开发、8 个月之后进行可视化锁定,在最后两个月中完成系统集成。一个完美的计划。
    项目组成员各自做着自己的工作,而随着可视化锁定日期的来临,他们开始进行代码集成。他们在可视化锁定最终截止日期前一天的下午2 点开始工作,但很快发现程序不能编译,更不用说运行了。代码在编译时有数十个错误,而似乎每处理一个错误就会产生10 个以上的新错误。他们一直干到午夜也没有结果,只好决定第二天再说。
    但测试发现问题的速度远比开发人员解决问题的速度快,处理系统这部分的错误经常会导致系统其他部分的问题。项目超期了,项目组成员在巨大的压力下工作,士气逐渐低落。最后,整个软件开发过程花了15 个月的时间,公司错过了非常好的的发布日期,市场份额也从第二位下降到第四位。

    生动的教材

    看到上面的那段话,你有什么感想?我只觉得如有芒刺在背:在我主持开发的一个证券业务系统中,几乎完全相同的故事就发生在我们的身上。在项目开始时,我们有近乎完美的计划;到最后,我们的项目拖延了50%的时间,让客户极其不满。你呢?难道你对这个故事没有似曾相识的感觉吗?
    这是《快速软件开发:有效控制与完成进度计划》中研究的第一个案例。在McConnell 的这本软件工程书籍里,这样生动的案例共有数十个。通过这些案例,以及无数准确而有说服力的统计数据,作者把“软件工程”用一种精确的语言描述出来。在这里,软件工程不是玄不可及的空谈,而是每天都发生在你身边的故事。
    作者在前言中这样写道:
    项目客户和项目经理对开发速度过慢的第一个反应经常是加大项目计划进度的压力,让开发人员超时工作。截至1995 年,有75%的大型项目和将近100%的超大型项目计划进度压力过重,将近60%的开发人员说他们感到工作压力在增加。美国的开发人员每周工作时间是48~50小时,甚至更多。许多人认为工作负担过重。
    在这样的环境中,软件开发人员的总体工作满意度在过去15 年中大幅度下降就不足为奇了。
    项目的进度计划依靠对开发人员工作的拼命挤压来完成,导致开发人员工作负担过重,他们很自然会告诉他们的朋友与家人:这一领域毫无乐趣可言。
    显然这一领域还是有乐趣的。我们大多数人以前都从事过这样的工作,因而我们并不苟同编写软件只是为获得报酬的说法。当然,在开发过程中的讨论会上确实会有一些不愉快的事情发生,但是这些不愉快大多会与快速开发的话题密切相关。是该在软件开发人员与项目进度这个海洋中设置一道堤坝了。本书中,我试图树立一个堤坝标杆,确保大海那边的狂潮不致大乱开发人员的正常工作。
    读者大可不必迷惑于本书的名字。所有的软件工程方法,其最终目的无非是在保证产品质量的前提下提高开发速度。这本书的主旨就是从软件工程学的角度来加速软件开发的过程。所以,你完全可以放心的把“快速软件开发”理解为“有效的软件开发”或“实用软件工程方法”,没有问题。另一方面,由于本书优美的格式和丰富的内容(不要着急,我还会专门介绍这些),以及作(译)者认真负责的态度和幽默诙谐的语言,我认为它完全可以并且应该成为一本传统软件工程(同样不要着急,我会在后面解释这个词)方面的高级教材。按照作者的说法,本书面向的读者是团队领导人、项目经理和程序开发人员。在阅读本书之前,读者应该具有软件工程方面的基础知识。

    传统软件工程的经典

    首先应该解释一下“传统软件工程”这个词。必须声明,这个词并未正式出现在任何科技文献中,乃是我凭着自己对软件工程的一点理解生造出来的,也没有非常严格的定义。在这里,“传统软件工程”是指1968 年德国NATO 会议之后产生的、以瀑布模型和结构化分析及设计为代表的一系列软件工程方法,其主要特征是强调生命周期前期的需求分析,不鼓励后期的需求变化。与之相对的,则是2001 年2 月“敏捷软件开发联盟”成立之后出现的各种敏捷开发方法。它们的主要特征是不做过多的前期分析,鼓励需求变化,甚至主动拥抱变化。其代表性的方法就是著名的XP(极限编程)[Bec, 00]。
    我也是一个程序员。看过了不少的编程书籍,迄今为止对我的编程能力和思想影响最大的,当属《设计模式》[GoF, 95]。不夸张的说,一本《设计模式》,让我的编程能力在两个月内提高了整整一个档次。为什么会有这样的奇效?Vlissides 教授曾经说过,设计模式的作用有两点:
    1. 用一种相似的格式记录所有人的经验,方便后来人阅读和理解。
    2. 为开发者提供通用的词汇表,方便开发者之间的交流。
    从这样的角度来看,《快速软件开发》这本书中非常重要的两个部分可以叫做“软件工程模式”(非常好的实践)和“软件工程反模式”(典型错误)。尽管它们面对的是软件工程领域而非程序设计领域,但是它们同样起着这两点作用,对于软件工程人员具有同样重要的指导意义。
    在本书的第三部分中,作者用了160 多个页码来介绍传统软件工程方法中的27 条“模式”。在以往的软件工程专著中,我曾经看到过这些方法中的一部分。但是作者不但将这些久经实践验证的方法归纳整理起来,并且用一种统一的格式来描述它们:首先是效果,包括缩短进度的潜力、可视性的改善、对风险的影响、一次成功的可能性、长期成功的可能性5 项量化指标;然后是实施该方法主要的风险;最后总结该方法与其他方法的相互影响和必须作出的权衡。只要有这样一张表,软件工程师就可以在一分钟之内评估出一种方法是否适用于自己的项目,并决定是否采用该种方法。
    来看一个例子(摘自第28 章,“外包”):
    外包就是把软件开发承包给第三方厂商而不是在公司内部开发。承包方在特定的领域有着较丰富的经验,能够在给定的时间内投入足够的开发人员,并且备有一个大的程序库可提供重用源码。由于上述因素,公司可以很快完成一个新项目。在一些情况下,外包能够节约开发成本。

    效果
    *** 缩短原定进度的潜力:极好
    *** 过程可视性的改善:无
    *** 对项目进度风险的影响:增大风险
    *** 一次成功的可能性:大
    *** 长期成功的可能性:很大

    主要风险
    *** 把专业知识扩散到其他公司去
    *** 失去对进一步开发的控制
    *** 泄露机密信息
    *** 丢失进度可视性和对进度的控制

    主要的相互影响和权衡

    *** 以失去控制和削弱公司内部的开发能力换来降低成本和提高开发速度。
    作何感想?在需要决定是否将某部分开发任务外包的时候,这个表可以帮助你迅速理清思路、作出判断;如果你和你的同事都看过本书,在谈起“外包”的时候,你们俩就会同时意识到“这意味着可能失去对进度的控制”。是的,作者凭借丰富的经验,对各种软件工程方法进行了有效的归纳、整理和评价,让读者可以快速掌握这些方法的精要,为读者提供极具表现力的词汇表,使读者可以很方便地将软件工程方法结合到自己的项目中来,而不是把软件工程看成象牙塔中不可触及的圣物。
    此外,在本书的第一、二部分中,作者围绕着“有效控制与完成进度计划”这个核心问题,将传统软件工程的方方面面都做了阐述,内容涵盖了软件开发中的基本原则、典型错误、风险管理、生命期计划、估算、进度计划、激励机制、团队合作、生产率工具、项目修复等等方面。熟悉传统软件工程的读者将会发现:从瀑布模型到面向对象,从COCOMO模型到快速原型,你学过的东西在本书中都有自己的位置。但是经过作者的组织,这些曾经让你感到如此抽象如此困难的东西却都变得如此触手可及、如此轻而易举。古诗有云“不识庐山真面目,只缘身在此山中”。而这本书则正是站在传统软件工程的最高点,高屋建瓴,自能给读者耳目一新的感觉。
    本书完稿于1995 年。经过多年的喧嚣和沉淀之后,传统软件工程在那个时候已经发展到了极致。而作为微软的高级顾问,作者McConnell 最擅长的就是“站在巨人的肩膀上”。所以,我可以放心的说:《快速软件开发》这本书堪称传统软件工程的经典。

    最后的经典

    所有学过“软件工程”这门课程的人都知道上世纪60 年代的软件危机、1968 年的NATO会议、以及著名的瀑布模型。从某种意义上来说,所有的传统软件方法都派生自瀑布模型和结构化软件开发方法。正如我在前面说过的,它们有一个共同的特点——强调前期的需求分析、不鼓励后期的需求变化。这一类的软件工程方法实际上带有建筑学方法的影子:先分析、再设计、最后实现;各个步骤有严格的区分,彼此之间不回溯或很少回溯;假设用户需求可以预先完全获取,并且很少变化;等等。
    很可惜,开发软件与盖房子有着本质上的区别。在软件开发的世界里,你很难预先捕捉到用户所有的需求,并且用户需求也常常发生变化。甚至有这样一种说法:在软件的世界里,唯一不变的就是变化[Sha, 02]。可是传统软件工程方法偏偏不能很好的应对变化,这就成了它们的致命伤。尽管传统软件工程方法也有许多发展,用各种不同的方式来应对需求的变化,但是这些方法都更多的采用“预先准备”的方法。所以,在需求变化越来越快、开发周期越来越短的今天,传统软件工程方法一方面发展到了极致,创造了非常大的生产力;另一方面也已积重难返,走到了生命的尽头。
    本书也是一样:一方面,它是传统软件工程的集大成者;另一方面,它也直接反映出了传统软件工程的致命弱点。下面是来自本书第19 章,“变更设计”的一个例子:“变更的设计”并不是指一种单一的设计方法学,而是一种能够使软件设计灵活的一系列设计活动。下面列出了一些这样的活动:
    *** 识别可能发生变更的区域
    *** 采用隐藏信息的方法
    *** 制定变更的计划
    *** 定义程序族
    *** 采用面向对象的设计方法
    看上去很美。但是,仅此而已。在传统的开发环境下,你没有准确识别变化需求的高层分析工具(现在仍然没有),也没有能快速应对变化的低层开发手段,所以这种方法实际上并不具有可操作性。也许一直到重构(refactoring)[Fow, 99]这种强大的代码级方法出现之后,这种“变更的设计”才真正有了实现的可能——但是,由于重构实在太强大、太方便了,程序员们干脆只在项目开始的时候做非常简单的设计,然后在后续的过程中用重构来改进系统的结构。这正是许多敏捷方法的做法。
    但是,尽管已经日暮西山、尽管已经老态龙钟,传统软件工程仍然对软件开发有着非常重要的指导意义,尤其是在项目管理方面。本书中的一些技术细节已经过时颇多,但是管理思想却是极其先进而且独到的。毕竟项目管理不象编程技术那样日新月异。所以对于项目经理和团队领导者来说,本书会很有价值;而如果你是想学习建模方法和软件设计方法,本书很可能会让你失望。
    前面已经提到过,《快速软件开发》成书于1995 年。在那以后,再没有一本传统软件工程方法的重量级著作问世,软件工程界的焦点也转移到了Rational 公司的UML这种建模工具上。随着敏捷方法的迅速崛起,软件工程方法的朝代更替已是近在眉睫。所以,这本集传统软件工程之大成的书,很可能也就是传统软件工程最后的经典了。

    好书,好译

    我必须承认,已经有好几年没有读到这么好的译本了(侯老师的翻译风格自成一派,而且又是“外来客”,且不拿他做比较)。最近两年,大家公认潘爱民老师的译文质量很高。但是我读潘老师译文,仍能直接联想到原文。而在《快速软件开发》中,我的确很少感觉到原文的味道,读来酣畅淋漓。对于许多句式、词汇,译者都做了精心的处理,让读者感觉是在看中文,而不是“透过汉字看英文”。以我个人之见,撇开对技术的掌握不谈,本书的翻译水平当在潘老师之上。注1
    不过,本书的翻译工作也有一些缺陷。由于本书是多人合译,所以在各个章节之间能明显感觉到语言风格的差异,甚至使用的术语也有差异。而且在第42 章中,译者将“User Interface”译为“用户接”,我觉得译为“用户界面”更贴切,不知道译者是否会采纳我的意见。瑕不掩瑜,这本《快速软件开发》仍然是近几年国内罕见的高质量计算机图书。尽管译本比原本晚了六、七年的时间,但是几位译者以如此负责的态度为我们翻译了如此精彩的图书,在此谨向他们致以崇高的敬意。
    一本在AMAZON上得到五颗星的书,一群肯下功夫的译者,一家有着优良传统的出版社。
    我有理由相信,《快速软件开发》是一本真正的好书。


    参考书目
    *[Bec, 00] Kent Beck, eXtreme Programming Explained: Embrace Change, AddisonWesley Longman, 2000.
    * [Fow, 99] Martin Fowler, Refactoring: Improving the Design of Existing Code, AddisonWesley Longman, 1999.
    * [GoF, 95]Eric Gamma, etc. Design Patterns: The Element of Reusable Object-OrientedSoftware, Addison Wesley, 1995.
    * [Sha, 02] Alan Shalloway, James Trott, Design Patterns Explained, Addison Wesley,2002.

0
相关文章