本文写作的主题为介绍在软件工程领域流行的两种软件开发模式——敏捷软件开发与传统软件工程,以及它们的优缺点。
一、传统软件工程
1,产生背景
传统软件工程(Software Engineering)的产生来源于上世纪60年代产生的软件危机。软件危机的产生是由于计算机计算能力和要处理的问题复杂度的急速增长。1972年,艾兹赫尔·戴克斯特拉于计算机协会图灵奖的演讲描述了软件危机产生的原因:
软件危机的主要原因是机器变得强大很多。直白的说,只要没有机器,编程便不会产生问题。当我们只有几台计算能力差的电脑,编程是一件容易的事情。而现在我们有了强大的计算机,编程自然也就成了一个大问题。——Edsger Dijkstra, The Humble Programmer (EWD340)
(笔者注:相信每个计算机科学领域的人,没有不知道Dijkstra的,他的Dijkstra算法无论任何算法书,任何算法课都会涉及的精妙算法,而他本人也是图灵奖的获得者,在学术界有很大的影响力。笔者本人也十分崇拜他。)
软件危机具体表现在:
- 项目运行超过预算
- 项目运行超过时间
- 软件十分低效
- 软件质量很低
- 软件无法满足需求
- 项目缺乏管理,代码难以维护
- 软件难以交付
正是由于计算机计算能力的显著提升,以及当时人们对软件的需求的提高,导致了人们意识到开发项目不能只是将程序员机械的组织在一起参与进行开发,而是需要使用系统而科学的管理模式,相互之间需要协调一致配合。于是学术界和工业界为了克服软件危机,提出了传统的软件工程开发方法,累积了大量的研究成果,广泛地进行大量的技术实践,将其发展为一门学科,甚至可以说是一个标准。
2,常见的传统软件工程模型
了解了传统软件工程的产生背景之后,下面介绍几种常见的传统软件工程模型。传统的软件开发模型包括瀑布模型、增量过程模型、原型模型、螺旋模型等。
(1)瀑布模型(Waterfall Model)
1970年温斯顿·罗伊斯(Winston Royce)提出了著名的“瀑布模型”,直到80年代早期,它一直是唯一被广泛采用的软件开发模型。瀑布模型是将软件生存周期的各项活动规定为按固定顺序而连接的若干阶段工作,形如瀑布流水,最终得到软件产品。
原始的瀑布模型将软件开发过程分为需求分析(Requirements),设计(Design),软件实现(implementation),测试(Verification),维护(Maintenance)五个周期。并且规定了它们自上而下、相互衔接的固定次序,如同瀑布流水,逐级下落。只有当上一级全部完成且检查无误后,开发才能从一个阶段“流动”到下一个阶段,这也是瀑布开发名称的由来。瀑布模型核心思想是按工序将大问题分为小问题,将功能的实现与设计分开,便于分工协作,即采用结构化的分析与设计方法将逻辑实现与物理实现分开。它的创作灵感,来源于当时发达的制造工业,流水线式的作业体系。一项产品就如同一个项目,在当时产品的制造采用分阶段流水,于是乎自然而然罗伊斯将其应用于软件开发。罗伊斯提出原始瀑布模型之后,不同的演变瀑布模型(包括Royce's 最终瀑布模型)在过程中略有改动。但基本保持原有的五大周期划分。比如引入了“回溯”机制,在当前阶段发现缺陷或需求不满足时,回到之前的某一周期,使之应对更加灵活,多变的现代项目要求。瀑布模型是传统软件开发模型中最典型的,也是其他传统软件开发的模型的基础。
(2)增量过程模型(Spiral Model)
增量过程模型是指每个阶段运用线性序列、每个增量提交产品。它是像原型和其他演化方法一样,具有迭代的特征,包括增量模型、RAD模型。增量过程模型融合了瀑布模型的基本成分(重复应用)和原型实现的迭代特征。该模型采用随着日程时间的进展而交错的线性序列,每一个线性序列产生软件的一个可发布的“增量”。
(3)原型模型(Prototype Model)
原型模型通过向用户提供原型获取用户的反馈,使开发出的软件能够真正反映用户的需求。同时,原型模型采用逐步求精的方法完善原型,使得原型能够“快速”开发,避免了像瀑布模型一样在冗长的开发过程中难以对用户的反馈作出快速的响应。相对瀑布模型而言,原型模型更符合人们开发软件的习惯,是目前较流行的一种实用软件生存期模型。
(4)螺旋模型(Spiral Model)
螺旋模型是一种演化软件开发过程模型,它兼顾了快速原型的迭代的特征以及瀑布模型的系统化与严格监控。螺旋模型最大的特点在于引入了其他模型不具备的风险分析,使软件在无法排除重大风险时有机会停止,以减小损失。同时,在每个迭代阶段构建原型是螺旋模型用以减小风险的途径。螺旋模型更适合大型的昂贵的系统级的软件应用。图中的四个象限1.决定目标,方案和限制2.评估方案,识别解决风险3.开发验证下一级产品4.计划下一个阶段,一圈如同原型模型开发的过程。
二、敏捷软件开发(Agile software development)
敏捷软件开发没有一个准确的定义,它来源于世纪之交时期。在90年代,当时盛行的复杂开发方法引起了程序员对其管理严格,高度规范的抱怨,为了解决这个问题,许多轻量的软件开发方法发展了出来。包括快速应用程序开发(rapid application development),动态系统开发方法(DSDM),Scrum开发方法等。它们现在被归于敏捷软件开发方法。
在2001,17名软件开发者在Snowbird会议上发布了敏捷软件开发宣言(the Manifesto for Agile Software Development),他们在其中提到:
- 个人与交互(Individuals and interactions):自我管理及自我驱动与结对编程这样的交互一样重要
- 可用的软件(Working software):可用的软件比文档更有用更受欢迎
- 客户合作(Customer collaboration):需求不可能在软件开发的开始全部得到,因此客户参与到开发中及其重要
- 应对改变(Responding to change):敏捷开发专注于快速应对持续变化的开发
从上面官方宣言中,其实可以看出敏捷开发更注重人与人的交互,快速应对开发过程中的变化。所以笔者认为敏捷开发的核心是敏捷,其中的Agile更确切的说是快速且灵活,它强调快速的开发可用软件,如何实现这一点呢,交流,交互,灵活适应变更。这就是我个人理解敏捷开发的宗旨。
下面介绍几种常见的敏捷开发方法,Crystal,透明水晶方法和Scrum让我们对敏捷开发有个初步的认识。
水晶方法Crystal
水晶方法,Crystal ,是由 Alistair Cockburn 和 Jim Highsmith 建立的敏捷方法系列,其目的是发展一种提倡“机动性的”方法。Crystal 方法适用于6-8名开发人员开发非生命攸关的系统。方法关注效率和适应性,注重人而不是过程。项目可以按照参加的人员和重要性划分。
重要性根据项目中的错误引发的后果分为:
C :Loss of comfort (某些不舒适)
D :Loss of discretionary money (经济损失)
E :Loss of Essential Money (严重经济损失)
L :Life Critical (生命危险)
一个项目称为C6说明参加人员在6人以下,重要性是C级,D20说明人员在6-20人,重要性是D级。
Crystal系列开发方法中,所适用的开发人员数量以及重要等级如下:
Crystal Clear适用于 C6,D6项目
Crystal Yellow适用于 C20,D20,E20项目
Crystal Orange 适用于 C40,D40,E40项目
Crystal Red 适用于 C80,D80,E80项目
Crystal方法有下列特征:
- 经常交付
- 反思改进
- 渗透式交流
- 个人安全
- 焦点
- 反思改进
- 配有自动测试、配置管理和经常集成功能的技术环境
Scrum
Scrum是一种灵活的软件管理过程框架,它可以帮助驾驭迭代、递增的软件开发过程,主要用于产品开发或工作管理。在这个框架中,开发人员分为了不同的角色,整个开发过程由若干个短的迭代(Sprint)周期组成,在每一次冲刺或迭代(一个15到30天的周期,其长度由开发团队决定)当中,开发团队创建可用的(可以随时推出)软件的一个增量。在冲刺中,每一天都会举行项目状况会议,被称为“Scrum”或“每日站立会议”。 每一个冲刺完成后,都会举行一次冲刺回顾会议,在会议上所有团队成员都要反思这个冲刺。举行冲刺回顾会议是为了进行持续过程改进。
Scrum案例的一个案例:荷兰铁路每天要运送120万乘客。该部门打造了一套全新的信息系统,为乘客提供更准确的列车信息,减少人为干预。这个PUB发布系统,利用的就是Scrum开发模式。具体详见:http://www.infoq.com/cn/articles/dutch-railway-scrum
三、特点分析与对比
传统软件工程开发模式作为第一个被提出的科学性开发方法,使得软件开发变得科学化、结构化,为软件开发提供了一套系统的开发路线。但是其缺点也在之后的数10年间显现出来:
传统软件工程开发模式的出现使得一开始无序混乱的软件开发变得有序、结构化,为软件开发提供了一套规整的、系统的开发路线,其一开始的确为软件开发带来了很大的好处。但传统软件工程开发模式这种较为单一的模式,其缺点也很快显现出来:
- 无法高效应对客户需求变化大的项目
- 开发是线性的,会导致错误的重复累积,对最终的测试和交付环节带来了很大的困难
- 没有考虑对于开发中很重要的组成部分——人
- 开发过程需要填写大量文档交予客户,拉低了效率
在上面的介绍中,敏捷开发可以很好地解决上述的缺点,它的诞生其实也是为了应对传统软件开发工程的不足。它的优点在于:
- 将开发关注点聚焦于个体,注重整个团队个体之间的交互,在协同开发中减少可能出现的问题以及加快问题的解决
- 将客户作为开发团队中的一员,将客户的需求放在第一位,使得再大的变动也可以很快的处理
- 开发周期相应的变短,交流变多。
- 不需要撰写过多的文档,内部的文档由每周一次的会议代替。
但这并不能说我们可以全部使用敏捷开发,抛弃传统软件开发,它也有其缺点,个人总结以下几条:
- 过于急躁的求快,而导致代码本身质量的下降,以及人员的工作量加重
- 太过于关注需求,导致开发过程十分被动,当客户的需求过多时,会导致团队原有的计划打乱
- 敏捷开发并不注重文档,而这就要求了开发人员自身的能力比较强,能够对于同伴所写代码快速理解吸收
- 敏捷开发将工程周期切成一个个的小部分,缺乏整体性,可能会导致系统的鲁棒性下降。
在软件需求极大的今天,我们要针对不同的项目特征使用不同的项目开发方法,在客户需求能够早期基本确定的情况下,传统方法,更加有效,对于项目需求不明确的项目敏捷开发更加适用。希望日后学术界能够提出更加普适的开发方法。
参考资料
1,维基百科:软件工程https://en.wikipedia.org/wiki/Software_engineering
2,维基百科:瀑布模型https://en.wikipedia.org/wiki/Waterfall_model
3,MBA百科:过程增量模型http://wiki.mbalib.com/wiki/Incremental_process_model
4,维基百科:敏捷软件开发https://en.wikipedia.org/wiki/Agile_software_development
5,CSDN博客:敏捷开发系列之旅 第四站(透明的Crystal水晶方法)http://blog.csdn.net/happylee6688/article/details/22625973
6,荷兰铁路公司的分布式Scrum开发http://www.infoq.com/cn/articles/dutch-railway-scrum
来源:博客园