文/金明
我们曾举办了一次为期三天的敏捷培训,学员主要是一些知名软件公司的项目经理和资深开发人员。整个培训结束后,从学员的回顾以及意见表上可以看出培训效果是显著的,但是学员也提到一些问题,主要是对敏捷方法学的实践和价值比较疑惑。在回答问题的同时,我们能感觉到随着敏捷方法学在国内被引入、被宣传,很多软件组织或人员对敏捷方法学都已经有了基本的了解,但是对敏捷方法学向软件行业承诺的价值还存在不同程度的顾虑。
以“交付更多客户价值”为核心原则,敏捷方法学向软件行业承诺:敏捷方法学能提升软件团队交付能力,给客户交付更多商业价值。为什么敏捷方法能做到这两点承诺?软件组织如果没有实施过敏捷方法学,或者实施方法不得当,通常会对是否在组织内部实施敏捷产生犹豫和观望情绪。我们来分析敏捷方法学是怎么做到的。
以“交付更多客户价值”为核心原则,敏捷方法学向软件行业承诺:敏捷方法学能提升软件团队交付能力,给客户交付更多商业价值。为什么敏捷方法能做到这两点承诺?软件组织如果没有实施过敏捷方法学,或者实施方法不得当,通常会对是否在组织内部实施敏捷产生犹豫和观望情绪。我们来分析敏捷方法学是怎么做到的。
敏捷方法学提升交付能力
提升软件团队的交付能力,其实最好的办法就是释放团队的软件生产力,而不是试图去规范它、约束它。这里,我们用“软件生产力”来定义软件团队开发软件的能力,包括软件团队在软件开发过程中为了解决各种各样的问题而使用的开发语言、开发工具以及开发实践。
软件生产力是不断发展的。为了解决软件开发过程中的问题,方法学才被提出来。从某种意义上讲,只有方法学积极采纳并改造新的软件生产力,而不是因循守旧地墨守成规,才能真正释放软件团队的软件生产力。
那么问题就变成:敏捷方法学如何采纳并改造现在的软件生产力?
现在的软件生产力
在开发语言方面,现在JVM/C#.NET是转为平台语言,支持在其基础上多语言开发,比如Jruby、Groovy、Jython等语言就能在JVM上运行。原来不受重视的脚本语言,像ruby、python等也是重登大雅之堂,给软件团体提供了更多的选择。
IDE:现代IDE不只是集成了编码、运行和调试功能的工具,而且是把应用程序开发的整个生命周期都纳入管理,从分析建模、代码编写、配置管理、构建管理,再到测试的集成,突破了原来软件过程里定义的各个环节的边界。一些大受好评的IDE无不是内建了ALM的支持,并集成了软件开发的大部分最佳实践,如Intellij IDEA。
Build tool:自动构建越来越受到开发团队的欢迎,Ant、nant、rake、gant……各种平台各种语言的build工具不仅提供了丰富的build task,而且给开发人员进行扩展提供了足够的自由度。至于maven,更是希望充当项目底层设施的角色,成为管理项目不可或缺的一部分。
Revision management tool:在项目开发过程中,版本管理非常重要。随着技术的发展,VSS这种笨重的工具早已被冲进历史的车轮。而且除了CVS、SVN这些central server的版本管理工具,分布式版本管理工具,如git、mercurial也是日益成熟。
前面只是简单列举了现在软件开发过程会用到的一些工具,其实,现在的软件开发实践也有非常鲜明的特征。很多在日常开发中涌现出来的开发实践,并不专属于特定的软件方法,却早已得到业界的认可。
Developer unit test:自Kent Beck的junit框架发布以来,人们才意识到开发人员写unit test也是如此的轻巧和方便。在其他语言方面,testNG、nunit、runit等测试框架也极大地推广了单元测试的编写。
Refactoring:重构是优化代码设计的重要手段之一,在Martin Fowler出版Refactoring之后,才真正被大家所关注。up-front design就逐渐被日常开发中的incremental design所取代。而随着对重构的研究,越来越多的相关书籍给开发人员提供了更多的实践指导,比如Refactoring to Pattern等。
Periodic auto build:因为SCM工具和integration tools出现,自动构建越来越受到开发团队的欢迎:一方面提高了软件产品的质量,减少了产品对特定环境的依赖;另一方面减少了重复乏味的工作,也给开发团队节省了时间和精力。像Cruisecontrol这样的开源工具出现之后,自动构建就时时刻刻都在进行,并能及时给开发团队提供反馈。
敏捷方法学释放生产力
那么,敏捷方法学里面如何对待这些软件生产力呢?我们以一些知名敏捷实践为例,看看这些实践与当前软件生产力之间是什么关系。
Test-Driven Development。
TDD的实践形式可以简单地归纳成:添加足够简单使得失败的测试,尽可能简单地修改功能代码使测试通过,重复这个过程;如果功能代码产生了bad smell,你需要重构来消除。用简单的方程式来描述,就是:
TDD = TFD + Refactoring
很明显,这个最有名的实践脱胎于unit test,又融合了重构的优点。“通过unit test可以改善代码质量”、“持续重构可以改善程序设计”,这些观点已经得到广泛认可。敏捷方法把developer unit test和重构吸收进来又加以改造,使得开发人员通过小步前进的方式获得更高的生产率,并交付更高质量的软件。而IDE集成ALM工具,更是让普通开发人员在应用TDD的开发过程中如虎添翼。
Pairing
Pairing 要求两个人在一起结对工作,双方不要求都是开发人员,可以是开发人员与商务分析人员,或者开发人员与质量分析人员,又或者是商务分析人员与质量分析人员,甚至是团队成员与客户。
坚持代码评审以及保持团队概念一致性是两项被很多经验证明能提高生产率和交付质量的实践。Pairing就把这两者做到了极致:编码设计的时候,始终有另外一个人在评审你的代码,从一开始就杜绝了不良设计和代码的引入;工作的时候,始终有另外一个人和你保持对概念理解的一致性,便于团队保持概念一致性。
Continuous Integration
有了持续集成服务器CruiseCon-trol或者Cruise、自动构建工具ant等等,版本管理工具,以及其他代码分析工具,比如测试覆盖率工具、checkstyle工具,持续集成涉及的功能越来越强大,不仅能自动快捷地给开发团队提供构建结果,而且能提供其他更多的分析结果以帮组开发团队改进软件质量。这样,开发团队通过快速得到构建反馈而提升了生产率,也可以凭借分析结果验证交付软件的质量。
敏捷方法实践还有很多,不管这些实践形式如何,其实都能从它们身上看到已经存在并被证明能提升生产率的开发实践。也就是说,敏捷方法学充分利用了已有的软件开发工具和开发语言的威力,极大地采纳了被证明了的软件开发实践,再按照一定的价值观和理念进一步改进这些实践。
从敏捷方法学对待现在软件生产力的态度,我们可以说敏捷方法学面对新兴软件生产力是积极采纳的,释放了软件团队最大的软件生产力,从而促进了软件团队交付能力的提升。
敏捷方法学交付更多价值
不管软件开发中使用什么样的开发方法学,最终交付的软件是只有给客户产生尽可能多的商业价值,软件项目才能说是成功的。
传统的形式化的、戒律森严的软件工程方法学,很多在具体实施的过程中都极大地偏离了“给客户交付价值”这个核心目标。因此,国际上一些著名的软件工程专家将传统的这些软件方法称之为“重方法”,强调对过程的极度严格要求。
与这些“重”方法不同,敏捷方法学就是以“给客户交付价值”为核心原则之一,而不是强调对过程的过度严格的管理。不仅在敏捷价值和原则里面紧扣“客户价值”,而且其所有实践都是客户价值驱动的。
对于软件开发来讲,客户关心的价值在哪些方面呢?在Amr Elssamadisy的Agile Adoption Patterns一书中,定义了如下的客户价值:
1.短的软件交付周期
2.及时的响应用户反馈
3.高的软件质量
4.软件的灵活性
5.项目团队的透明性
6.低的软件成本
7.高的投资回报率(ROI)
这些客户价值都是紧密联系在一起的,这里我们就只针对第1、3、7三个方面来做一些相关的阐述。
短的软件交付周期
软件交付得越早,交付周期越短,客户就能越早通过使用软件产品来创造自己的价值,特别是商业软件:这是很显然的。即使你交付的软件只包括了完整功能列表里的一部分,但因为那对客户而言是价值最高的部分,而且软件是可以运转的,客户也就得到了更多的价值。不仅仅是完整周期的缩短,更频繁的交付、增进的发布也能给客户带来商业价值。
在传统软件方法学里面,只有到软件交付期限才能交付给客户可用的软件版本。整个软件开发过程里面,客户得不到一个可运行的版本来使用。这样,就严重损害了客户的价值。
在敏捷方法学里面,项目团队通过INVEST的user story划分,保证了客户价值的周期性交付;通过简单设计来保持关注对客户而言优先级最高的user story,避免了其他低价值付出;而通过持续集成来保证每个构建出来的版本都是客户可用的候选发布版本……这样,通过多种紧凑的实践,敏捷方法学保证了项目团队对客户价值的关注和尽早实现,并随时提供能满足一定客户价值的可用的软件版本。
高的软件质量
软件质量越高,也就意味着软件的缺陷越少,提供的功能更加符合客户真正想要的要求。而且,即使商业需求上发生了变化,高质量的软件也容易进行扩展和修改。
在传统软件方法学里面,也有通过详尽的user case设计、代码评审、QA测试用例等方式来减少软件可能出现的缺陷。但因为分析、设计、开发和测试等环节的脱节,不同环节之见的理解不同,沟通不畅,很难挖掘客户真正的需求和适应需求变化,从而导致大部分最后的软件要么是缺陷多多,要么是功能不能满足客户需求,只能留到二期三期来解决。
在敏捷方法学里面,项目团队通过co-location,打破不同部门之间的隔板,让所有的项目成员坐在一起,减少了软件需求在沟通过程中的失真。如果有现场客户,就更是让这种信息失真问题减到最低。
在开发过程中,敏捷团队会使用TDD、简单设计和持续集成等实践来保证软件的简单,让可能存在的问题尽早的暴露出来;再通过小型sign off,来保证开发人员做出的软件是满足分析人员和测试人员的要求。
高的投资回报率(ROI)
出资方最关心的莫过于投资回报率(ROI)了。除了前面分析的软件质量和软件成本之外,对ROI有直接影响的因素就是软件生命周期。软件生命周期是指软件的产生直到报废的整个生命周期。生存周期越长,说明软件能满足用户要求、能被使用的时间周期越长。而软件生命周期又与软件的可维护性和灵活性息息相关。那么,如何保证软件的可维护性和灵活性,就是影响到客户的ROI的关键因素。
在传统软件开发学里面,基本上只有靠一开始的软件设计来提供软件的灵活性。虽然开发过程上游的软件设计的设计方案可能非常优雅,但由于中间过程没有足够的验证和约束,等到软件交付的时候,软件最后实现的可维护性和灵活性完全不能保证。这样,客户就只能祈祷软件的生命周期不要那么短了。
而在敏捷方法学里面,很多开发实践可以提升软件的可维护性和灵活性,比如前面分析的TDD、持续集成和增进设计等等,从而使软件的生命周期得到了极大的延长。因此,这些影响产品生命周期的实践对客户的投资回报率都是有直接或间接的影响。
从上面的分析可以看出,敏捷方法实践就是以“交付更多客户价值”为出发点提出来的,始终体现了敏捷方法学的价值观:“个体和交互胜过流程和工具,可工作的软件胜过面面俱到的文档,客户合作胜过合同谈判,响应变化胜过遵循计划”,和以“尽早、持续的交付有价值的软件来使客户满意”原则为首的敏捷原则。
敏捷实施调查
2008年2月,Dr. Dobb's发起的敏捷开发技术实施情况调查结果显示:实施敏捷方法之后,开发生产率得到提高的占82%,软件交付质量得到提升的占77%,而客户满意度得到提升的则占78%。2008年6月,敏捷工具厂商Versionone发起的敏捷开发实施情况调查显示:实施敏捷方法之后,开发生产率得到提高的占84%,软件交付质量得到提升的占68%,69%的软件项目加快了上市时间,而另外有74%的人认为项目风险降低了。
从上面两次调查报告来看,绝大部分的组织都认为实施敏捷方法学之后,组织的软件交付能力得到了提升,而且客户的满意度也得到了提高。也就是说,在绝大部分实施敏捷方法学的软件组织里面,敏捷方法学承诺的两个愿景得到了充分的印证。
2008年2月,Dr. Dobb's发起的敏捷开发技术实施情况调查结果显示:实施敏捷方法之后,开发生产率得到提高的占82%,软件交付质量得到提升的占77%,而客户满意度得到提升的则占78%。2008年6月,敏捷工具厂商Versionone发起的敏捷开发实施情况调查显示:实施敏捷方法之后,开发生产率得到提高的占84%,软件交付质量得到提升的占68%,69%的软件项目加快了上市时间,而另外有74%的人认为项目风险降低了。
从上面两次调查报告来看,绝大部分的组织都认为实施敏捷方法学之后,组织的软件交付能力得到了提升,而且客户的满意度也得到了提高。也就是说,在绝大部分实施敏捷方法学的软件组织里面,敏捷方法学承诺的两个愿景得到了充分的印证。
结论
敏捷方法学承诺的“提升团队交付能力,给客户交付更多商业价值”的确能给项目团队和软件客户带来实实在在的好处。不仅有充足的理由,而且有充足的案例数据来证明这一点。面对商业价值日新月异的经济趋势,传统的软件方法学显得束手无策,既不能满足目前对软件交付商业价值的要求,也极大地扼杀了软件团队的生产力和创造力。与“重”方法学不同,敏捷方法学只是提供了很少的几种推荐实践,然后再提供了遵循的价值和原则。敏捷方法学更希望软件团体在开发过程中,根据客观的实际情况,按照敏捷价值和原则,进行裁剪出适合团队的软件方法。基于此,也使越来越多的软件组织投入到实施敏捷方法学的潮流中来。
作者简介:
金明,华中科技大学硕士,ThoughtWorks公司咨询师,SCJP,系统分析师。他对机械模具、数字安全证书,以及海洋航运等行业的企业应用开发拥有超过4年的经验。在加入ThoughtWorks公司后,他开始投入到敏捷方法学的实践之中,特别对敏捷实施、项目管理、面向对象分析和设计等方面感兴趣。
金明,华中科技大学硕士,ThoughtWorks公司咨询师,SCJP,系统分析师。他对机械模具、数字安全证书,以及海洋航运等行业的企业应用开发拥有超过4年的经验。在加入ThoughtWorks公司后,他开始投入到敏捷方法学的实践之中,特别对敏捷实施、项目管理、面向对象分析和设计等方面感兴趣。
(本文来自《程序员》杂志0902期)
原文链接:https://www.f2er.com/javaschema/287890.html