软件研发

【专家视点】传统软件开发方式的挑战和机遇

2016-08-17 16:10:27 | 来源:中培企业IT培训网

自20世纪50年代开始软件开发以来,人们一直在探索软件开发的方法。中培课堂专家王老师指出,目前,软件开发过程一般被划分为若干个目的和作用相对独立活动,包括:需求、分析、设计、实现、测试和集成,以及维护。围绕着如何安排、规划这些活动的次序、周期和历时,人们提出过各种各样的软件开发方法模型。

我们将具有以下特点的软件开发方法定义为传统软件开发方法:

l 以预测性为原则

l 以文档驱动开发过程

l 以过程控制为核心

面对激烈的市场竞争,要求持续满足不断变化的需求,传统软件开发方法的特点也成为了它的弊病,应对下面各种挑战时显得力不从心:

l 如何减少开发过程中的浪费

l 如何准确,及时的适应需求变更

l 如何持续演进系统架构

l 如何保证软件系统的长期质量

l 如何实现安全重构(Refactoring)

l 如何最大限度的降低系统集成的成本

l 如何在团队中共享知识,使团队成员共同成长

l 如何合理的进行成本和时间估算

l 如何迅速获得软件开发收益

在传统软件工程方法中,软件开发的生命周期固定的划分为若干顺序的阶段(需求、分析、设计、实现、集成测试和维护),如下图所示。整个流程的特点是:

l 不完成上一个阶段就不能进入下一个阶段

l 直到流程中期的开发阶段(Implementation)才开始真正的编码;之前所有阶段的“成果”均以文档形式体现

l 测试和集成(Testing and Integration)被认为是对开发阶段的辅助或者收尾,往往晚于开发阶段开始

l 维护阶段成本高昂

下面主要从需求分析,设计,实现和维护四方面来分析传统开发模式的问题。

1. 需求分析

传统需求分析一般以名为“需求规格说明书”(Requirement Specification)的文档为目标,以固定时长(根据项目规模而定,一般2、3周或者更长)为约束,以完成需求文档为结束。

经历过传统需求分析过程的分析师和开发人员都会有类似的感觉:

l 无论用多长时间来分析需求,总感觉需求没有完备

l 无论如何研讨,已有的需求总感觉不能百分之百明确

l 至项目开发后期,业务部门和技术部门往往就需求产生纠纷,一般有两种形式:

1. 技术部门认为频繁的需求变更不但增加项目压力,更使已有开发工作浪费

2. 业务部门认为软件系统不能跟进,影响业务发展

传统需求困境分析

造成上述传统需求分析方法困境的原因主要有两点:

l 在项目进行的过程中,业务需求本身也在发展变化,从而引发软件需求变化。

l 业务人员不可能凭空把所有需求都想清楚,只有看到、用到真实的软件之后,才能逐渐把自己的需求弄清楚。

虽然一次性需求存在诸多问题,但现实中,技术部门和业务部门往往都希望能在这个阶段将所有问题想清楚。促使团队这样做的深层原因在于:

l 从管理的角度考虑,软件项目需要申请预算

l 从软件开发的角度考虑,需求的每一次变更都需要长的时间和巨大的成本来应对,这是技术部门和业务部门双方都不愿看到的。为了避免项目中进行可能的风险,双方都宁可在项目初期尽量把需求冻结。

第一个原因与项目计划方式有关;第二个原因与其说是对策,不如说是对传统开发方法缺陷的妥协:对企业级应用系统来说,早期需求冻结不仅是无法做到,而且还会带来一项隐性的浪费——这种项目开发出来后,可能有20~30%的功能从上线开始,已经不再需要;10~20%的功能的生命周期不超过半年,即费用和人力有相当一部分投入到无用的功能开发中。  

业务部门和开发团队依赖文档进行沟通的后果往往是理解出现偏差,开发出的系统的不能满足业务部门的真正需求,造成浪费。

2. 设计

在传统开发方法中,架构设计是围绕着设计文档展开的。具体实施过程有如下特点:

l 预先设计。在实际开发工作开始前,少数架构师们需要用相当长的一段时间来进行架构设计和详细设计,力求得到一个具有高度可扩展性的良好架构。产出为“概要设计文档”和“详细设计文档”。根据项目规模,这个过程一般持续数周、数月甚至数年不等

l 短暂评估。架构师产出的设计文档要经过架构设计评审委员会或类似组织的评审,这个过程一般持续数天

l 依据设计进行实现。经过评审的设计会交到开发者手中,进行实际的编程实现,这个过程往往以数月,甚至数年来计算。

思考传统架构设计方法,我们不禁要提出这样的问题:

为什么传统开发方法会如此重视前期预先架构设计,以至于希望在实际开发前把架构设计做到尽善尽美?

答案在于,在传统的概念中,一旦设计成型,架构是很难调整的。例如,传统的软件工程教科书中都会讨论“架构调整的成本”问题:如果在设计中实现一次修改的成本为1;在实现过程中相同修改的成本就是5~10;在测试、部署阶段,同样的修改成本将上升到50~100;维护阶段同样修改的成本更是成指数曲线上升。

这种策略存在一个根本问题:软件的“扩展”究竟会如何发生是很难预计的。面对这一困境,传统开发方法的解决方案是继续增加预先设计的时间和人力,但往往收效甚微。

传统设计困境分析

传统预先设计方法恶性循环的原因有三点,对应上述实施过程的特点:

l 设计和实现脱节。设计评审团专家一般不参与实际的软件开发。基于经验的设计一方面无法得到实现的验证;另一方面,当需求发生变更时,无法随之演进。

l 评估的可靠性有限。对预先设计评估的只能基于已知的需求,而系统的可扩展性是在应对变更的需求时体现出来的,因此评估具有很大的局限性

l 实现者缺少对预先设计进行修改的支持。当预先设计不能满足实际需求时,开发者或者修改设计,或者置需求变更不理,继续沿预先设计开发。忽视需求变更的结果只能是系统无法满足应用(而开发者也可以将责任推到架构师身上);如果开发者根据需求修改设计,则预先设计不但事实上已经成为浪费,而且已有的设计和实现往往更成会增加修改的难度。原因在于,如果预先设计的扩展性没有用到,则这些额外的扩展性带来的对当前需求无用的复杂性,这些复杂性增加了理解、修改系统的难度。

3. 实现

软件实现的质量在某种程度上可以决定项目成败。决定实现质量的因素有两个:

l 缺陷(或称为Bug)的数量

l 增加新功能的难易程度

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

l 随着Bug产生和发现之间的时间被延长,发现Bug原因的难度就更大

l Bug数量众多,相互间的关系变得更为复杂,修复的成本就更高

l Bug修复的效果难以确认,往往修改一个地方,就有可能破坏其他功能点,导致整个系统的BUG率长时间不收敛

l Bug数量长时间不收敛,开发团队逐渐失去信心,不敢再随便修改,从而导致实现新需求的难度更大

l 迫于进度压力,技术部门不愿进行更改,与业务部门的关系紧张

为了保证实现质量,采用传统开发方法的团队也做了很多努力,例如明文规定单元测试覆盖率、定时进行代码复审等。但效果未必理想,一种情况是:由于实现和测试在实现时间上分离,测试运行不及时、不频繁,在进度压力下,这些制度往往不能真正落实;另一种情况是:很多测试只是追求覆盖率,没有真正起到充分测试的作用,甚至出现假测试。代码复审会议也流于形式,对于改进代码质量的帮助不大。于是我们看到一个现象:一边是公司不断强调质量管理,另一边软件还是Bug重重,代码修改难度很大。由此可见,要保证软件质量,只有制度还是不够的。  

大型企业级应用系统往往是由多个模块或者子系统组成的,因此除了基本的开发活动,与系统质量、成败密切相关的另一个问题是集成。

传统开发方法通常在开发结束之后才进行系统集成和验收测试,这就导致这个阶段成了一个问题高发阶段。系统经常在集成阶段集成不起来,大量以前没有预料到的BUG突然出现,团队需要花费很多时间来解决这些问题,给项目造成了很大的风险。有些项目,在开发实现阶段感觉已经接近结束了,但一到集成阶段就问题重重,使得“上线”成了一件令人恐惧的辛苦工作,需要在客户现场加班加点才能成功上线。再加上验收测试突然提出大量修改意见,愈发增加了这一阶段的工作量和难度。

传统实现方法困境分析

造成上述困境的主要原因是:

l 测试人员介入产品测试较晚,一方面导致,随着系统的不断增大,很多缺陷被埋藏的很深,很难发现;另一方面,在接近发布的时点发现很多问题,留给开发人员修复的非常少,导致只能带着缺陷发布

l 需求通过文档传递,开发人员和测试人员理解常常有偏差。如果需求文档更新不及时,还会导致很多无效的工作

l 没有自动化的测试和持续集成环境的情况,集成和测试的成本很高,所以无法频繁的进行这种有效的质量保证活动

l 在开发过程中,开发人员更多考虑功能实现,而忽视了代码质量、设计的优化和可测试性,导致后期修改代码成本很高

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

l 可测试性是架构设计的试金石。不可测试的系统往往模块间依赖关系混乱,功能划分不清晰,理解困难,导致出现Bug后难以发现原因,新需求也难以加入

l 从敏捷开发的角度看,测试还具有如下功能和目标:

1. 最准确、可运行的系统设计文档

2. 测试驱动系统设计

3. 自动化测试更好的支持重构,从而使架构演进成为可能

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

4. 维护

随着业务的发展,以及用户对软件系统的理解加深,新的情况会不断涌现。

l 在日复一日使用过程中,一些在验收测试中没有发现的缺陷也会浮现出来

l 随着业务数据量的增加,系统对性能的要求也会比最初构建是提高

l 开发和维护通常是不同的团队,开发过程中很多的知识没有被传递给维护人员

l 随着市场的变化和客户在使用中发现新的价值,新的需求会被提出

这些都对维护 提出了很高的要求。

传统维护方法的困境

l 系统的灵活性较差,较大范围的调整和新增功能困难

l 没有得到及时更新的文档不能反映系统的真实情况,即使文档内容正确,单纯通过文档很难真正理解一个系统

l 人员的变更对系统的影响很大

如果不能及时的对客户的要求进行响应,会降低客户满意度,使客户丧失很多市场的机会。

标签: 软件开发