[ZT]代码地震(作者:王咏刚 2004 年1 月)(1)
代码地震 (王咏刚 2004 年1 月) 1 问题引入 很不幸,这又是一次失败的软件开发经历。 一个经验丰富的项目经理率领着七个身手不凡的程序员,用了五个月时间为某银行开发了一套“银证通”管理系统——在这里,大家用不着细究“银证通”系统的具体流程和功用,我们只要知道这是一套涉及银行、证券公司、客户三方的实时交易和转账系统就足够了。因为系统需要连接位于不同物理位置、隶属于不同企业或机构的后台服务,需要通过尽可能多的手段向客户提供7×24 小时的交易服务(这是一种典型的异构环境下的分布式电子商务模型),项目组决定选择Web Service 作为系统的核心支撑技术,并选用C#语言来编码实现。五个月的开发顺利结束, 项目组已经成功地构建出了如图 1 所示的一套功能齐备、结构清晰、符合组件服务模型要求的应用系统。 图 1 系统架构示意图 图 1 显示,系统主要由两个分布在异地的Web Service 服务程序和三种不同类型(GUI、Web、呼叫中心)的客户程序组成。两个服务程序都通过ADO.NET 数据访问接口分别与各自的数据库连接。服务程序B 因为要在复杂的并发条件下管理共享资源,比服务程序A 多了一个并发控制组件。三种类型的客户程序都通过SOAP 协议调用服务程序提供的Web Service 接口完成交易功能。 开发工作结束以后,项目组几乎没碰到什么真正的困难就成功地在客户现场完成了系统的安装和调试。系统在实际运行环境下表现良好,无论是功能还是性能都可以满足用户的需要。看上去,这个项目自始至终都那么十全十美,如果不是三个月以后发生的那起突发事件,项目经理和他那些满怀自信的组员们一定可以在年终时拿到全公司最高的奖金了。 系统正式运行的第三个月末,客户提出要更改一下系统的功能。其实,这算不上什么特别大的功能调整。简单说来,就是客户改变了现有的业务制度,在新制度的要求下,“银证通”系统需要增加一项新的业务代码,并在另一项原本由数字构成的业务代码前增加3 个英文字母组成的前缀。 项目经理只瞥了一眼《需求变更说明书》,就非常有把握地对负责该项目的销售人员说:“小意思,一个人一天时间就能摆平。这样吧,为了稳妥起见,你可以向客户承诺三天内解决问题,五天内新版本正式上线。” 当然,事情并不像项目经理想象的那样简单——如果一切顺利的话,我也就不用在这里多费口舌了——就是这样一次看似轻松的修改工作,让整个项目组陷入了困境。好吧,我们现在就来看看,需求变更提出以后,项目组里到底发生了什么。 第一天,项目经理根据自己“一个人一天时间就能摆平”的判断,要求程序员甲在一天的时间内独立完成所有相关代码的改动和系统测试。 第二天一早,项目经理惊讶地发现,倒霉的程序员甲两眼通红、一夜未眠,还在埋头查找和修改代码。不得已, 程序员乙在项目经理的安排下,也加入到了代码修改者的行列中来。 第三天,情况依然没有好转,项目经理的心中隐约产生了不祥的预感。 第四天,距离对客户承诺的最后期限越来越近了。项目经理又将程序员丙补充到了修改小组中。 第五天清晨,参加修改工作的三名程序员一致认为, 所有与新需求相关的代码改动都已完成,可以着手对新系统进行测试了。项目经理立即调来了两名专门负责测试的程序员。不幸的是,测试工作从一开始就陷入了混乱。起初是系统无法在测试环境中顺利运行,在好几次重新编译和链接之后,客户端和服务端程序才能正常启动;接下来, 程序员们发现,系统中有两项重要交易无法完成;更糟糕的是,在执行压力测试时,服务程序很快就会失去响应.. 第五天、第六天、第七天都在周而复始的Bug 报告、代码调试、Bug 定位、代码修改、编译链接中飞逝而过,