传统方法中在课上大规模介绍的就是瀑布模型。此博客首先通过将敏捷开发模型与瀑布模型相互比较来对比一下两者的优劣。
在对比两者优劣之前,先大致介绍一下两者的特点。
瀑布模型将软件生命周期分为制定计划、需求分析、软件设计、程序编写、软件测试和运行维护等六个基本活动,并且规定了他们自上而下、相互衔接的固定次序。我自己对于这个开发架构的理解就是:由于这个架构之中从制定计划到最后的运行维护过程中需求分析只在前期进行了一次,在后面就没有专门的需求分析过程,这个时候在需求变化的时候就很难去有效地响应变化。因此,这个瀑布模型具有的缺点就是难于很好地表达和描述用户的需求。其优点是与一般系统工程一致,易于使用,不要求特别的技术与工具也能很好地进行软件开发。
传统方法当然不仅限于瀑布模型,还包括增量模型、原型模型、螺旋式模型等等。由于瀑布式模型是一种使用比较普遍的模型,并且我们着实需要一个具体的模型来探讨传统软件开发模式与敏捷开发模式的异同,我们就暂且先用瀑布模型作为传统方法的典型来说明。在文章的最后可以再探讨一些其它传统方法自身具有的优势。
下面介绍敏捷开发,我们将重点放在极限编程以及Scrum上。
首先我们先介绍敏捷开发的宣言,我觉得2001年17位软件开发者发表的“敏捷软件开发宣言”在一定程度上可以反映这个思想的灵魂:
1. Individuals and interactions over processes and tools.
2. Working software over comprehensive documentation.
3. Customer collaboration over contact negotiation.
4. Responding to change over following a plan.
它的基本原则有迭代式开发、增量交付、互动式开发、持续集成等。根据这些原则,我们也可以在一定程度上理解它所具有的一些优点例如高质量、高速度、高效率等。敏捷开发是一种以人为核心、迭代、循序渐进的开发方法。在敏捷开发中,软件开发的构建被切分成多个子项目,各个项目都成果都经过测试,具备集成和可运行的特征。这个特征正好对应了宣言中的第二条。换言之,敏捷开发中将一个大项目分为了很多相互联系但也可以独立运行的小项目,并分别完成,在此过程中软件一直处于可使用状态。敏捷开发路线图如下:
Test-Driven Development -> Continuous Integration -> Refactoring -> Pair-Programming -> Stand Up -> Frequent Releases -> Minimal Documentation -> Collaborative Focus(Sharing the codes) -> Customer Engagement -> Automated Testing -> Adaptive Planning
总体来看敏捷开发相对于传统方法的优势,它更强调改进,善于吸收其他方法的优点。它的这种迭代式开发和增量交付的模式中有很多传统方法的痕迹。个人觉得敏捷开发更加注重现实生活中软件开发的本质并且能够找到之前所有传统方法中最match软件开发实际过程的优点,将这些优点整合起来并且加入一些新的思想,就有了我们现在看到的敏捷开发思想。
下面我们重点介绍敏捷开发相比于传统开发的一些优势:
在分工方面,传统方法阶段划分分明,每个阶段由不同的人来完成。我认为这样有几点劣势:首先,做不同阶段的人不会过多关注其它阶段的开发人员的情况,参与度并不高,并且整个团队中大家的收获会比较小,有点闭门造车的感觉,因为只有与不同阶段的人的交流才能使大家对整个项目有不同的认识。而且,每个项目的不同阶段本身就是相互联系的。举个自身经历的例子来讲。我们在通过摄像头捕捉的图像来进行人物再识别的过程中会有很多个阶段。首先,我们需要对摄像头捕捉的不同场景下的人进行图像预处理,然后识别前景和背景,然后对人物提取特征,然后进行特征融合最后进行人物搜索匹配。在对图像预处理的阶段,我们的文档虽然对人物有明确的要求,但是不可避免的是图像的预处理一定会对图像的特征提取产生无可估量的影响。只有这两者相互交流,不断迭代才可能找到最匹配的一组预处理与特征提取的方法。相应的,特征提取阶段中哪些特征是比较可靠的这一信息在特征融合阶段中也会起到至关重要的作用。整体性能的提升是很需要相互交流的。
从第一点我们也可以推想到我们所说的第二个传统方法的缺点,大量文档。各个阶段在交付的时候都必须说明自己阶段所做的工作以方便以后阶段的工作,因此这会大大增加大家的工作量。
在需求分析方面,传统方法要求用户需求明确,而且在瀑布模型中我们可以清楚地看到用户只有一次提出需求的机会。但是在实际的软件开发过程中,软件的需求往往是变化的(在各种程序员的吐槽中也可见一斑)。瀑布模型很难适应这样的变化。螺旋模型等其它传统方法中尽管有很大的改进,但是相比于敏捷开发模型,还是后者更加适应需求的快速变化因为后者是主动做到拥抱变化的。
在驱动力方面。传统方法是文档驱动的,而敏捷模型中是测试驱动开发。首先文档比测试枯燥太多,其次,最终用户的使用就是对程序的终极测试所以测试驱动的方法明显更加高效。
在客户参与方面,传统方法开发软件的过程是顾客与开发团队的利益博弈,在开发过程中顾客参与程度不高。在敏捷开发中,顾客和开发团队一起开发,代码归团队所有而不是不同人拥有不同模块的代码。这样每个人都能够熟悉整个项目的代码,团队的人员变动相比传统方法来说影响会小很多
在集成方面,传统方法中集成是在后期的一个重要阶段,它是一个独立的阶段。集成是一件很痛苦的事情, 通常很长时间才会做一次集成,这时候的集成往往问题众多,要进行调试的话,难度很大。 一般来说,人在这个过程中,容易产生疲劳感。敏捷开发中,软件集成很频繁,每一次集成的改变也很少,即使集成失败也容易定位错误。而且敏捷开发往往是自动化测试的。
在周期方面,传统方法往往要到最后才能得到可执行产品,而敏捷开发很早就可以得到可执行产品,方便以后测试导向的开发。
当然敏捷开发还有自己的一些劣势:
1.顾客和开发团队是两个不同的组织,在企业文化和工作习惯上都是有差异的。我自己还在这个过程中产生了一些疑问,在现实生活中,软件开发的工程在某些技术和算法上还是保持着自己的专利权的,他们需要防止侵权。但是如果采用了敏捷开发模型的话,代码就要和另外一个组织的人共享,这是一个很难实现的过程不是吗?也欢迎大家在评论区讨论这个问题~
2.敏捷开发欢迎需求的转变而过多的需求转变可能会扰乱整个软件开发。
3.很多需求是客户在团队中口头提出的,可能在验收过程中有不明确和冲突的问题。
4.过于激进的敏捷开发导致过于草率地开始编程从而导致了代码需要大改或者返工,反而慢。
5.敏捷开发对于人们的交际沟通能力远高与传统方法,这方面可能会出现问题。
简单总结以上,
传统模型:
用户必须等到开发的后期才能看到产品,使得产品周期变得很长。
测试与检验都在开发的后期,因此前期一些错误可能会积累到后期才被发现,开发风险大大增加。
阶段固定,需求分析完后需求很难再更改。
各阶段间产生大量文档,极大增加了工作量。
敏捷开发:
敏捷开发强调可用的产品,敏捷开发过程会尽快开发出可交付的产品,产品周期将会变短。
敏捷开发中要求客户也作为开发团队一部分,强调开发者、客户之间更多的交流,因此能更好地对需求进行理解。
交流的变多同时避免了许多不必要的文档。
短的开发周期、多的交流以及追求简洁的开发原则使得整个开发过程非常便于适应变更。
以上就是两者的对比,为了增进读者理解,笔者提供一个典型敏捷开发模型:极限编程模型。
XP包含了类似于瀑布模型中的四个过程:需求分析、设计、编码和测试。虽然说过程类似,但过程中所用的思想与方法却与传统开发有所不同。下面简要介绍这四个关键活动。
· 需求分析——客户应该是项目开发队伍中的一员,而不是和开发人员分开的;因为从项目的计划到最后验收,客户一直起着很重要的作用。开发人员和客户一起,把各种需求变成一个个小的用户故事(UserStory),它们都被记录在一些故事卡(StoryCard)上,客户根据每个模块的商业价值来指定它们的优先级;开发人员要做的是确定每个需求模块的开发风险,风险高的(通常是因为缺乏类似的经验)需求模块将被优先研究、探索和开发;经过开发人员和客户分别从不同的角度评估每个模块后,它们被安排在不同的开发周期里,客户将得到一个尽可能准确的开发计划;客户为每个需求模块指定验收测试(功能测试)。
· 设计——XP提倡对于简单的设计(SimpleDesign),就是用最简单的方式,使得为每个简单的需求写出来的程序可以通过所有相关的单元测试。
· 编码——XP就提倡结对编程(PairProgramming)。结对编程的好处是,一个人编写代码时另一个人在思考。如果编码者遇到障碍,他们就交换位置。如果两个人都遇到障碍,他们的讨论可能被在这个区域工作的其他人听到,可能给出帮助。
· 测试——XP就提倡在开始写程序之前先写单元测试。一个人的单元测试组织到一个“通用测试集”,每天都可以进行系统的集成和确认测试。
参考文献:
[1]梁永幸 浅谈敏捷开发与传统开发方式的区别 2012.12《电子世界》
[2]王冲 敏捷开发与传统瀑布模型的比较及教学 2011.4 《电子世界》