传统的困境和敏捷的方案----实现


归根到底,软件实现质量决定项目成败。决定实现质量的因素有两个:

  1. 缺陷(或称为Bug)的数量
  2. 增加新功能的难易程度

传统实现方法的困境

众所周知,无论开发者如何小心,随着开发的不断进行,系统中缺陷(或称为Bug)的数量都在不断积累。在传统软件开发方法中,测试往往被推迟到实现之后进行,因而不断积累的Bug不能被及时的发现和修复。这将带来如下后果:

  1. 随着Bug产生和发现之间的时间被延长,发现Bug原因的难度就更大
  2. Bug数量众多,相互间的关系变得更为复杂,修复的成本就更高
  3. 由于开发过程中没有自动化测试,Bug修复的效果难以确认,往往修改一个地方,就有可能破坏其他功能点,导致整个系统的BUG率长时间不收敛
  4. 长时间Bug数量不收敛,开发团队逐渐失去信 心,不敢再随便修改,从而又满足新需求的难度更大
  5. 迫于进度压力,技术部门不愿进行更改,与业务部门的关系紧张

为了保证实现质量,采用传统开发方法的团队也做了很多努力,例如明文规定单元测试覆盖率、定时进行代码复审等。但效果未必理想,一种情况是:由于实现和测试在实现时间上分离,测试运行不及时、不频繁,在进度压力下,这些制度往往不能真正落实;另一种情况是:很多测试只是追求覆盖率,没有真正起到充分测试的作用,甚至出现假测试。代码复审会议也流于形式,对于改进代码质量的帮助不大。于是我们看到一个现象:一边是公司不断强调质量管理,另一边软件还是Bug重重,代码修改难度很大。由此可见,要保证软件质量,只有制度还是不够的。
大型企业级应用系统往往是由多个模块或者子系统组成的,因此除了基本的开发活动,与系统质量、成败密切相关的另一个问题是集成。
传统开发方法通常在开发结束之后才进行系统集成和验收测试,这就导致这个阶段成了一个问题高发阶段。系统经常在集成阶段集成不起来,大量以前没有预料到的BUG突然出现,团队需要花费很多时间来解决这些问题,给项目造成了很大的风险。有些项目,在开发实现阶段感觉已经接近结束了,但一到集成阶段就问题重重,使得“上线”成了一件令人恐惧的辛苦工作,需要在客户现场加班加点才能成功上线。再加上验收测试突然提出大量修改意见,愈发增加了这一阶段的工作量和难度。

传统实现方法困境分析

随着人们对软件开发认识的加深,可测试性(testability)逐渐被提升到了开发活动中第一要素的位置。而传统软件开发方法陷入困境的原因恰恰在于对可测试性的忽视。除了基本的验证功能的正确性,可测试还具有更深层次的含义:

  1. 可测试性是架构设计的试金石。不可测试的系统往往模块间依赖关系混乱,功能划分不清晰,理解困难,导致出现Bug后难以发现原因,新需求也难以加入
  2. 在敏捷方法的测试驱动开发中,测试还具有如下功能和目标:
    1. 最准确、可运行的系统设计文档
    2. 测试驱动系统设计
    3. 测试支持重构,从而使架构演进成为可能

在传统开发方法中,代替自动化测试的往往是大量的手工测试,这样测试除了成本高、耗时长外,还存在难以保证测试一致性和质量,从而无法担当起保证软件质量的重任,更对架构设计毫无贡献。

敏捷实现解决方案

敏捷实现的核心实践包括:

  1. 测试驱动开发
  2. 结对编程
  3. 持续重构
  4. 简单设计
  5. 持续集成

测试驱动开发并不是简单的“先写测试,还是后写测试问题”,该实践的要点在于“驱动”二字,体现在三个方面:

  1. 先于产品代码(production code)编写的测试本质上是对需求的可执行化表示,因而当测试通过时,产品代码也就满足了需求
  2. 先于产品代码的测试从调用者的角度定义产品代码的应用程序接口(Application Program Interface,简称API),从而使API定义更为准确:既没有冗余、浪费,也没有遗漏。从这个意义上说,测试驱动了模块或子系统级别的设计
  3. 最准确、可运行的系统设计文档
  4. 测试支持重构。任何内部实现的改进都有对应的测试保证其正确性和系统行为的一致性,从而使架构演进成为可能

应用测试驱动开发的最佳实践是结对编程,在结对过程中,通过结对双发的交流、讨论、轮流编写测试和实现,可以实现:

  1. 知识共享
  2. 持续代码复审(Review)
  3. 新成员迅速融入

持续重构是测试驱动开发的关键一环,也是系统演进的手段,而简单设计则是系统演进的目标。
简单设计不代表简陋的设计,简单的设计往往是历经重构、精炼才能得到的。简单的设计易于理解、易于添加新的功能、易于维护,随着需求的变更,以及开发者对领域的认识加深,当前的简单设计有可能不再使用,进而又需要通过重构实现需求变更后的简单设计。可以看出:测试驱动开发,重构,简单设计是环环相扣,互相支持的,而进行这些实践的最佳方式就是结对编程。
在敏捷项目中,系统集成不再是某个特定阶段才有的活动。集成自始至终贯穿整个开发活动,从“某个离散时间点上的活动”转变为“开发过程中不断进行的连续活动”。例如,在我们的敏捷项目中,一般一对开发者一天内会继承5~10次之多,则一个由5~6对开发者组成的团队一天可能会集成25~50次之多。这样,集成的成本和风险都被平摊到了最低限度,而由集成引发的Bug也能在第一时间得到修复。

软件定制开发

关于Topideas | 战略合作 | 内容合作 | 渠道合作 | 版权商标 | 隐私声明 | 工作机会 | 联系我们

Copyright © 2012 Topideas 版权所有

湖北 - 武汉 | 各个商标由其各自所有者持有 鄂ICP备13005502

咨询(客服) 咨询(客服)

欢迎给我们留言