敏捷开发知识集

在软件工业界,敏捷开发已成为众多高效开发团队的制胜之道。它不仅被许多中小公司青睐,在全球一百强的企业中,敏捷开发也已大行其道,受到许多资深项目管理者和开发人员的推崇。到2008年,欧美软件企业中,有近半企业已采用敏捷方法进行开发。大多数尚未应用敏捷的企业,也都对其有所了解,而且很多在计划实施。中国的外企,外包公司和许多知名企业也都开始采用了敏捷方法。例如,腾讯内部几乎所有的开发团队都在实施敏捷。

敏捷方法给这些企业也已带来了巨大的收益。据业内资深人士和长期从事敏捷咨询的服务公司透露,采用敏捷开发的团队一般会提高3-10倍的效率,软件的质量也有了更加可靠的保证。同时,敏捷开发的应用也给团队内的每个成员提供了良好的发展机会。他们的技术和合作水平都能得到响应的提高。敏捷的成功来源于其方法本身的适用性和团队对它的深入理解和合理运用。下面我们就对敏捷开发做一个简单的介绍和讨论。

敏捷不是指某一种具体的方法论、过程或框架,而是一组价值观和原则。符合敏捷价值观和原则的开发方法包括:极限编程(XP),Scrum,精益软件开发(Lean Software Development),动态系统开发方法(DSDM),特征驱动开发(Feature Driver Development),水晶开发(Crystal Clear)等等。所有这些方法都具有以下共同特征:

1. 迭代式开发。即整个开发过程被分为几个迭代周期,每个迭代周期是一个定长或不定长的时间块每个迭代周期持续的时间一般较短,通常为一到六周。

2. 增量交付。产品是在每个迭代周期结束时被逐步交付使用,而不是在整个开发过程结束的时候一次性交付使用。每次交付的都是可以被部署到用户应用环境中被用户使用的、能给用户带来即时效益和价值的产品。

3. 开发团队和用户反馈推动产品开发。敏捷开发方法主张用户能够全程参与到整个开发过程中。这使需求变化和用户反馈能被动态管理并及时集成到产品中。同时,团队对于用户的需求也能及时提供反馈意见。

4. 持续集成。新的功能或需求变化总是尽可能频繁地被整合到产品中。一些项目是在每个迭代周期结束的时候集成, 有些项目则每天都在这么做。

5. 开发团队自我管理。拥有一个积极的、自我管理的、具备自由交流风格的开发团队,是每个敏捷项目必不可少的条件。人是敏捷开发的核心。敏捷开发总是以人为中心建立开发的过程和机制,而非把过程和机制强加给人。

许多人认为,相比于“传统”的瀑布开发模式,敏捷开发是一种“现代”的开发模式。但是,实际上敏捷方法,特别是迭代和增量开发方法(IID)起源于20世纪30年代的一些非软件项目。而最早引入一些敏捷方法的项目之一就是20世纪60年代初的美国航天局水星计划。在这个项目中,一些极限编程方法如测试先行等也被使用。此后,迭代和增量开发被IBM联邦系统部(FSD)和沃森研究中心(Watson Research Center)采纳。有趣的是一些研究人员甚至在关于瀑布开发模式的最早的论文中发现了敏捷开发的线索。在这篇论文中,温斯顿.罗伊斯(Winston Royce)建议在一个项目中使用两次瀑布模式,也就是使用两次迭代。

20世纪70年代,最早的有记载的使用迭代和增量开发的主要项目之一,是为第一艘美国三叉戟潜艇开发的第一指挥和控制系统。该项目有大约一百万行代码,进行得非常成功。迭代和增量开发从此开始稳步发展,越来越多的项目开始使用这种开发模式。在1976年,Tom Gilb在他的著作《软件度量》(“Software Metrics”)一书中阐述了他的迭代和增量开发实践,这可能就是第一部阐述这种方法的书籍。迭代和增量开发的另一次出色发挥,是在一个美国宇航局航天飞机软件的开发项目。这个项目负责开发其航空电子设备的软件系统。该项目由IBM联邦系统部(IBM FSD)在1977至1980年完成。一些典型的敏捷做法,如使用8个周迭代以及用反馈推动开发循序渐进等方法都在该项目中得以应用。

20世纪80年代,更多的出版物和更多的项目应用进一步推进了迭代开发的发展。在1895年,巴里贝母(Barry Boehm)正式定义了使用迭代开发的螺旋模型(Spiral model)。80年代初,在美国国防部发生了一件有趣的事情。美国国防部一直以来都要求其软件开发商在开发过程中使用严格的瀑布开发模型。但是到了1987年末,国防部开始“建议”使用迭代和增量开发作为软件开发模式。后来美国国防部的项目审查显示,早期使用瀑布模式开发的软件项目,有75%以失败告终,有些开发出来的产品根本没有被使用过,只有2%的软件产品无需大量修改就能被正常使用。

20世纪90年代,推荐使用迭代和增量开发的出版物和文献显著增加。在经历了多次有“瀑布心态”(‘waterfall mentality’)项目的失败之后,美国国防部开始“要求”而不是像80年代那样仅仅是“建议”他们的软件开发商使用IID开发模式。Rational统一开发过程(Rational Unified Process)也是在这一时期产生并发展起来的,它具有更规范的迭代渐进过程。到2000年底,更多的敏捷开发方法被广泛推广并被使用于各种不同的项目中。2001年二月,一组由17位在DSDM,XP,Scrum,FSD等领域的专家组成的代表团齐聚美国犹他州,寻找这些方法的共同点。最终,这些专家制定并宣布了敏捷开发宣言。由此形成了现在我们所认识的敏捷开发和后来的敏捷联盟。

敏捷联盟官方网站:http://www.agilealliance.org/

关键词:敏捷开发

2001年2月11日到13日,17位软件开发领域的领军人物聚集在美国犹他州的滑雪胜地雪鸟(Snowbird)雪场。经过两天的讨论,“敏捷”(Agile)这个词为全体聚会者所接受,用以概括一套全新的软件开发价值观。这套价值观,通过一份简明扼要的《敏捷宣言》传递给世界,同时即宣告了敏捷开发运动的开始。

《敏捷宣言》

我们通过身体力行和帮助他人来揭示更好的软件开发方式。经由这项工作,我们形成了如下价值观:

 个体与交互 重于 过程和工具
可用的软件 重于 完备的文档
客户协作   重于 合同谈判
响应变化   重于 遵循计划

在每对比对中,后者并非全无价值,但我们更看重前者。

17位敏捷宣言发起人名单如下:

Kent BeckMike Beedle
Arie van BennekumAlistair Cockburn
Ward CunninghamMartin Fowle
James GrenningJim Highsmith
Andrew HuntRon Jeffries
Jon KernBrian Marick
Robert C. MartinSteve Mellor
Ken SchwaberJeff Sutherland
Dave Thomas 

关键词:敏捷开发宣言

 

在敏捷开发中,我们遵循以下准则:

  1. 我们的最高目标是,通过尽早和持续地交付有价值的软件来满足客户。
  2. 欢迎对需求提出变更——即使是在项目开发后期。要善于利用需求变更,帮助客户获得竞争优势。
  3. 要不断交付可用的软件,周期从几周到几个月不等,且越短越好。
  4. 项目过程中,业务人员与开发人员必须在一起工作。
  5. 要善于激励项目人员,给他们以所需要的环境和支持,并相信他们能够完成任务。
  6. 无论是团队内还是团队间,最有效的沟通方法是面对面的交谈。
  7. 可用的软件是衡量进度的主要指标。
  8. 敏捷过程提倡可持续的开发。项目方、开发人员和用户应该能够保持恒久稳定的进展速度。
  9. 对技术的精益求精以及对设计的不断完善将提升敏捷性。
  10. 要做到简洁,即尽最大可能减少不必要的工作。这是一门艺术。
  11. 最佳的架构、需求和设计出自于自组织的团队。
  12. 团队要定期反省如何能够做到更有效,并相应地调整团队的行为。

关键词:敏捷开发,敏捷原则

 

极限编程

极限编程(英语:Extreme programming,缩写为XP),是一种软件工程方法学,是敏捷软件开发中应用最为广泛和最富有成效的几种方法学之一。如同其他敏捷方法学,极限编程和传统方法学的本质不同在于它更强调可适应性而不是可预测性。极限编程的支持者认为软件需求的不断变化是很自然的现象,是软件项目开发中不可避免的、也是应该欣然接受的现象;他们相信,和传统的在项目起始阶段定义好所有需求再费尽心思的控制变化的方法相比,有能力在项目周期的任何阶段去适应变化,将是更加现实更加有效的方法。

极限编程为管理人员和开发人员开出了一剂指导日常实践的良方;这个实践意味着接受并鼓励某些特别的有价值的方法。支持者相信,这些在传统的软件工程中看来是“极端的”实践,将会使开发过程比传统方法更加好的响应用户需求,因此更加敏捷,更好的构建出高质量软件。

极限编程的创始者是肯特·贝克、沃德·坎宁安和罗恩·杰弗里斯,他们在为克莱斯勒综合报酬系统(C3)的薪水册项目工作时提出了极限编程方法。肯特·贝克在1996年3月成为C3的项目负责人,开始对项目的开发方法学进行改善。他写了一本关于这个改善后的方法学的书,并且于1999年10月将之发行,这就是《极限编程解析》(2005第二版出版)。克莱斯勒在2000年2月取消了实质上并未成功的C3项目,但是这个方法学却一直流行在软件工程领域中。至今,很多软件开发项目都一直以极限编程做为他们的指导方法学。

极限编程的目标

极限编程的主要目标在于降低因需求变更而带来的成本。在传统系统开发方法中,系统需求是在项目开发的开始阶段就确定下来,并在之后的开发过程中保持不变的。这意味着项目开发进入到之后的阶段时出现的需求变更将导致开发成本急速增加,而这样的需求变更在一些发展极快的领域中是不可避免的。

极限编程通过引入基本价值、原则、方法等概念来达到降低变更成本的目的。一个应用了极限编程方法的系统开发项目在应对需求变更时将显得更为灵活。

极限编程的12个核心实践

短交付周期

极限编程和Scrum一样采用迭代的交付方式,每个迭代1-3周时间。在每个迭代结束的时候,团队交付可运行的,经过测试的功能,这些功能可以马上投入使用。

计划游戏

XP的计划过程主要针对软件开发中的两个问题:预测在交付日期前可以完成多少工作;现在和下一步该做些什么。不断的回答这两个问题,就是直接服务于如何实施及调整开发过程;与此相比,希望一开始就精确定义整个开发过程要做什么事情以及每件事情要花多少时间,则事倍功半。针对这两个问题,XP中又两个主要的相应过程:

软件发布计划(ReleasePlanning)。客户阐述需求,开发人员估算开发成本和风险。客户根据开发成本、风险和每个需求的重要性,制订一个大致的项目计划。最初的项目计划没有必要(也没有可能)非常准确,因为每个需求的开发成本、风险及其重要性都不是一成不变的。而且,这个计划会在实施过程中被不断地调整以趋精确。

周期开发计划(IterationPlanning)。开发过程中,应该有很多阶段计划(比如每三个星期一个计划)。开发人员可能在某个周期对系统进行内部的重整和优化(代码和设计),而在某个周期增加了新功能,或者会在一个周期内同时做两方面的工作。但是,经过每个开发周期,用户都应该能得到一个已经实现了一些功能的系统。而且,每经过一个周期,客户就会再提出确定下一个周期要完成的需求。在每个开发周期中,开发人员会把需求分解成一个个很小的任务,然后估计每个任务的开发成本和风险。这些估算是基于实际开发经验的,项目做得多了,估算自然更加准确和精确;在同一个项目中,每经过一个开发周期,下一次的估算都会有更过的经验、参照和依据,从而更加准确。这些简单的步骤对客户提供了丰富的、足够的信息,使之能灵活有效地调控开发进程。每过两三个星期,客户总能够实实在在地看到开发人员已经完成的需求。在XP里,没有什么“快要完成了”、“完成了90%”的模糊说法,要不是完成了,要不就是没完成。这种做法看起来好像有利有弊:好处是客户可以马上知道完成了哪些、做出来的东西是否合用、下面还要做些什么或改进什么等等;坏处是客户看到做出来的东西,可能会很不满意甚至中止合同。实际上,XP的这种做法是为了及早发现问题、解决问题,而不是等到过了几个月,用户终于看到开发完的系统了,然后才告诉你这个不行、那个变了、还要增加哪个内容等等。

结对编程

结对编程是指代码由两个人坐在一台电脑前一起完成。一个程序员控制电脑并且主要考虑编码细节。另外一个人主要关注整体结构,不断的对第一个程序员写的代码进行评审。

结对不是固定的:我们甚至建议程序员尽量交叉结对。这样,每个人都可以知道其它人的工作,每个人都对整个系统熟悉,结对程序设计加强了团队内的沟通。这与代码集体所有制是息息相关的。

可持续的节奏

团队只有持久才有获胜的希望。他们以能够长期维持的速度努力工作,他们保存精力,他们把项目看作是马拉松长跑,而不是全速短跑。

代码集体所有

代码集体所有意味着每个人都对所有的代码负责;这一点,反过来又意味着每个人都可以更改代码的任意部分。结队程序设计对这一实践贡献良多:借由在不同的结队中工作,所有的程序员都能看到完全的代码。集体所有制的一个主要优势是提升了开发程序的速度,因为一旦代码中出现错误,任何程序员都能修正它。

在给予每个开发人员修改代码的权限的情况下,可能存在程序员引入错误的风险,他/她们知道自己在做什么,却无法预见某些依赖关系。完善的单元测试可以解决这个问题:如果未被预见的依赖产生了错误,那么当单元测试运行时,它必定会失败。

编码规范

XP开发小组中的所有人都遵循一个统一的编程标准,因此,所有的代码看起来好像是一个人写的。因为有了统一的编程规范,每个程序员更加容易读懂其他人写的代码,这是是实现代码集体所有的重要前提之一。

简单设计

XP中让初学者感到最困惑的就是这点。XP要求用最简单的办法实现每个小需求,前提是按照这些简单设计开发出来的软件必须通过测试。这些设计只要能满足系统和客户在当下的需求就可以了,不需要任何画蛇添足的设计,而且所有这些设计都将在后续的开发过程中就被不断地重整和优化。

在XP中,没有那种传统开发模式中一次性的、针对所有需求的总体设计。在XP中,设计过程几乎一直贯穿着整个项目开发:从制订项目的计划,到制订每个开发周期(Iteration)的计划,到针对每个需求模块的简捷设计,到设计的复核,以及一直不间断的设计重整和优化。整个设计过程是个螺旋式的、不断前进和发展的过程。从这个角度看,XP是把设计做到了极致。

测试驱动开发

测试驱动开发的基本思想就是在开发功能代码之前,先编写测试代码,然后只编写使测试通过的功能代码,从而以测试来驱动整个开发过程的进行。这有助于编写简洁可用和高质量的代码,有很高的灵活性和健壮性,能快速响应变化,并加速开发过程。

测试驱动开发的基本过程如下:

① 快速新增一个测试

② 运行所有的测试(有时候只需要运行一个或一部分),发现新增的测试不能通过

③ 做一些小小的改动,尽快地让测试程序可运行,为此可以在程序中使用一些不合情理的方法

④ 运行所有的测试,并且全部通过

⑤ 重构代码,以消除重复设计,优化设计结构

简单来说,就是不可运行/可运行/重构——这正是测试驱动开发的口号

重构

XP强调简单的设计,但简单的设计并不是没有设计的流水账式的程序,也不是没有结构、缺乏重用性的程序设计。开发人员虽然对每个USERSTORY都进行简单设计,但同时也在不断地对设计进行改进,这个过程叫设计的重构(Refactoring)。这个名字最早出现在MartinFowler写的《Refactoring:ImprovingtheDesignofExistingCode》这本书中。

Refactoring主要是努力减少程序和设计中重复出现的部分,增强程序和设计的可重用性。Refactoring的概念并不是XP首创的,它已经被提出了近30年了,而且一直被认为是高质量的代码的特点之一。但XP强调,把Refactoring做到极致,应该随时随地、尽可能地进行Refactoring,只要有可能,程序员都不应该心疼以前写的程序,而要毫不留情地改进程序。当然,每次改动后,程序员都应该运行测试程序,保证新系统仍然符合预定的要求。

系统隐喻

为了帮助每个人一致清楚地理解要完成的客户需求、要开发的系统功能,XP开发小组用很多形象的比喻来描述系统或功能模块是怎样工作的。比如,对于一个搜索引擎,它的Metaphor可能就是“一大群蜘蛛,在网上四处寻找要捕捉的东西,然后把东西带回巢穴。”

持续集成

集成软件的过程不是新问题,如果项目开发的规模比较小,比如一个人的项目,如果它对外部系统的依赖很小,那么软件集成不是问题,但是随着软件项目复杂度的增加(即使增加一个人),就会对集成和确保软件组件能够在一起工作提出了更多的要求-要早集成,常集成。早集成,频繁的集成帮助项目在早期发现项目风险和质量问题,如果到后期才发现这些问题,解决问题代价很大,很有可能导致项目延期或者项目失败。

持续集成是一种软件开发实践,即团队开发成员经常集成它们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。许多团队发现这个过程可以大大减少集成的问题,让团队能够更快的开发内聚的软件。

现场客户

在极限编程中,“客户”并不是为系统付帐的人,而是真正使用该系统的人。极限编程认为客户应该时刻在现场解决问题。例如:在团队开发一个财务管理系统时,开发小组内应包含一位财务管理人员。客户负责编写故事和验收测试,现场客户可以使团队和客户有更频繁的交流和讨论。

极限编程的4个价值

除了XP实践,极限编程还提倡四大价值:沟通、简单、回馈、勇气。

沟通

构建一个软件系统的基本任务之一就是与系统的开发者交流以明确系统的具体需求。在一些正式的软件开发方法中,这一任务是通过文档来完成的。

极限编程技术可以被看成是在开发小组的成员之间迅速构建与传播制度上的认识的一种方法。它的目标是向所有开发人员提供一个对于系统的共享的视角,而这一视角又是与系统的最终用户的视角相吻合的。为了达到这一目标,极限编程支持设计、抽象、还有用户-程序员间交流的简单化,鼓励经常性的口头交流与回馈。

简单

极限编程鼓励从最简单的解决方式入手再通过不断重构达到更好的结果。这种方法与传统系统开发方式的不同之处在于,它只关注于对当前的需求来进行设计、编码,而不去理会明天、下周或者下个月会出现的需求。极限编程的拥护者承认这样的考虑是有缺陷的,即有时候在修改现有的系统以满足未来的需求时不得不付出更多的努力。然而他们主张“不对将来可能的需求上投入精力”所得到的好处可以弥补这一点,因为将来的需求在他们还没提出之前是很可能发生变化的。为了将来不确定的需求进行设计以及编码意味着在一些可能并不需要的方面浪费资源。而与之前提到的“交流”这一价值相关联来看,设计与代码上的简化可以提高交流的质量。一个由简单的编码实现的简单的设计可以更加容易得被小组中的每个程序员所理解。

反馈

XP团队重视反馈,反馈越快越好。在极限编程中,“反馈”是和系统开发的很多不同方面相关联的:

来自系统的反馈:通过编写单元测试,程序员能够很直观的得到经过修改后系统的状态。

来自客户的反馈:功能性测试是由客户还有测试人员来编写的。他们能由此得知当前系统的状态。这样的评审一般计划2、3个礼拜进行一次,这样客户可以非常容易的了解、掌控开发的进度。

来自小组的反馈:当客户带着新需求来参加项目计划会议时,小组可以直接对于实现新需求所需要的时间进行评估然后反馈给客户。

反馈是与“交流”、“简单”这两条价值紧密联系的。为了沟通系统中的缺陷,可以通过编写单元测试,简单的证明某一段代码存在问题。来自系统的直接反馈信息将提醒程序员注意这一部分。用户可以以定义好的功能需求为依据,对系统进行周期性的测试。用Kent Beck的话来说:“编程中的乐观主义是危险的,而及时反馈则是解决它的方法。”

勇气

极限编程理论中的“系统开发中的勇气”最好用一组实践来诠释。其中之一就是“只为今天的需求设计以及编码,不要考虑明天”这条戒律。这是努力避免陷入设计的泥潭、而在其他问题上花费了太多不必要的精力。勇气使得开发人员在需要重构他们的代码时能感到舒适。这意味着重新审查现有系统并完善它会使得以后出现的变化需求更容易被实现。另一个勇气的例子是了解什么时候应该完全丢弃现有的代码。每个程序员都有这样的经历:他们花了一整天的时间纠缠于自己设计和代码中的一个复杂的难题却无所得,而第二天回来以一个全新而清醒的角度来考虑,在半小时内就轻松解决了问题。

极限编程的5个原则

组成极限编程基础的原则,正是基于上面描述的那几条价值。在系统开发项目中,这些原则被用来为决策做出指导。与价值相比,原则被描述的更加具体化,以便在实际应用中更为简单的转变为具体的指导意见。

1. 快速反馈

当反馈能做到及时、迅速,将发挥极大的作用。一个事件和对这一事件做出反馈之间的时间,一般被用来掌握新情况以及做出修改。与传统开发方法不同,与客户的发生接触是不断反复出现的。客户能够清楚地洞察开发中系统的状况。他/她能够在整个开发过程中及时给出反馈意见,并且在需要的时候能够掌控系统的开发方向。

单元测试同样对贯彻反馈原则起到作用。在编写代码的过程中,应需求变更而做出修改的系统将出现怎样的反应,正是通过单元测试来给出直接反馈的。比如,某个程序员对系统中的一部分代码进行了修改,而假如这样的修改影响到了系统中的另一部分(超出了这个程序员的可控范围),则这个程序员不会去关注这个缺陷。往往这样的问题会在系统进入生产环节时暴露出来。

2. 假设简单

假设简单认为任何问题都可以”极度简单”地解决。传统的系统开发方法要考虑未来的变化,要考虑代码的可重用性。极限编程拒绝这样做。

3. 增量变化

极限编程的提倡者总是说:罗马不是一天建成的。一次就想进行一个大的改造是不可能的。极限编程采用增量变化的原则。比如说,可能每三个星期发布一个包含小变化的新版本。这样一小步一小步前进的方式,使得整个开发进度以及正在开发的系统对于用户来说变得更为可控。

4. 拥抱变化

可以肯定地是,不确定因素总是存在的。“拥抱变化”这一原则就是强调不要对变化采取反抗的态度,而应该拥抱它们。比如,在一次阶段性会议中客户提出了一些看来戏剧性的需求变更。作为程序员,必须拥抱这些变化,并且拟定计划使得下一个阶段的产品能够满足新的需求。

5. 高质量的工作

没人喜欢拖泥带水,每个人都期望出色的完成工作。极限编程的提倡者认为范围、时间、成本和质量这个四个软件开发的变量,只有质量不可妥协的。

关键词:敏捷开发,极限编程

 

持续集成(CONTINUOUS INTEGRATION)

集成软件的过程不是新问题,如果项目开发的规模比较小,比如一个人的项目,如果它对外部系统的依赖很小,那么软件集成不是问题,但是随着软件项目复杂度的增加(即使增加一个人),就会对集成和确保软件组件能够在一起工作提出了更多的要求-要早集成,常集成。早集成,频繁的集成帮助项目在早期发现项目风险和质量问题,如果到后期才发现这些问题,解决问题代价很大,很有可能导致项目延期或者项目失败。

大师Martin Fowler对持续集成是这样定义的:

持续集成是一种软件开发实践,即团队开发成员经常集成它们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。许多团队发现这个过程可以大大减少集成的问题,让团队能够更快的开发内聚的软件。

持续集成的价值

  • 减少风险

一天中进行多次的集成,并做了相应的测试,这样有利于检查缺陷,了解软件的健康状况,减少假定。

  • 减少重复过程

减少重复的过程可以节省时间、费用和工作量。说起来简单,做起来难。这些浪费时间的重复劳动可能在我们的项目活动的任何一个环节发生,包括代码编译、数据库集成、测试、审查、部署及反馈。通过自动化的持续集成可以将这些重复的动作都变成自动化的,无需太多人工干预,让人们的时间更多的投入到动脑筋的、更高价值的事情上。

  • 任何时间、任何地点生成可部署的软件

持续集成可以让您在任何时间发布可以部署的软件。从外界来看,这是持续集成最明显的好处,我们可以对改进软件品质和减少风险说起来滔滔不绝,但对于客户来说,可以部署的软件产品是最实际的资产。利用持续集成,您可以经常对源代码进行一些小改动,并将这些改动和其他的代码进行集成。如果出现问题,项目成员马上就会被通知到,问题会第一时间被修复。不采用持续集成的情况下,这些问题有可能到交付前的集成测试的时候才发现,有可能会导致延迟发布产品,而在急于修复这些缺陷的时候又有可能引入新的缺陷,最终可能导致项目失败。

  • 增强项目的可见性

持续集成让我们能够注意到趋势并进行有效的决策。如果没有真实或最新的数据提供支持,项目就会遇到麻烦,每个人都会提出他最好的猜测。通常,项目成员通过手工收集这些信息,增加了负担,也很耗时。持续集成可以带来两点积极效果:

(1)有效决策:持续集成系统为项目构建状态和品质指标提供了及时的信息,有些持续集成系统可以报告功能完成度和缺陷率。

(2)注意到趋势:由于经常集成,我们可以看到一些趋势,如构建成功或失败、总体品质以及其它的项目信息。

  • 建立团队对开发产品的信心

持续集成可以建立开发团队对开发产品的信心,因为他们清楚的知道每一次构建的结果,他们知道他们对软件的改动造成了哪些影响,结果怎么样。

持续集成的要点

1.统一的代码库

2.自动构建

3.自动测试

4.每个人每天都要向代码库主干提交代码

5.每次代码递交后都会在持续集成服务器上触发一次构建

6.保证快速构建

7.模拟生产环境的自动测试

8.每个人都可以很容易的获取最新可执行的应用程序

9.每个人都清楚正在发生的状况

10.自动化的部署

 持续集成的原则

1. 所有的开发人员需要在本地机器上做本地构建,然后再提交的版本控制库中,从而确保他们的变更不会导致持续集成失败。

2. 开发人员每天至少向版本控制库中提交一次代码。

3. 开发人员每天至少需要从版本控制库中更新一次代码到本地机器。

4. 需要有专门的集成服务器来执行集成构建,每天要执行多次构建。

5. 每次构建都要100%通过。

6. 每次构建都可以生成可发布的产品。

7. 修复失败的构建是优先级最高的事情。

关键词:敏捷开发,持续集成

 

测试驱动开发

测试驱动开发,英文全称Test-Driven Development,简称TDD,是一种不同于传统软件开发流程的新型的开发方法。它要求在编写某个功能的代码之前先编写测试代码,然后只编写使测试通过的功能代码,通过测试来推动整个开发的进行。这有助于编写简洁可用和高质量的代码,并加速开发过程。

Kent Beck先生最早在其极限编程(XP)方法论中,向大家推荐“测试驱动”这一最佳实践,还专门撰写了《测试驱动开发》一书,详细说明如何实现。经过几年的迅猛发展,测试驱动开发已经成长为一门独立的软件开发技术,其名气甚至盖过了极限编程。

基本原理

测试驱动开发的基本思想就是在开发功能代码之前,先编写测试代码,然后只编写使测试通过的功能代码,从而以测试来驱动整个开发过程的进行。这有助于编写简洁可用和高质量的代码,有很高的灵活性和健壮性,能快速响应变化,并加速开发过程。

测试驱动开发的基本过程如下:

① 快速新增一个测试

② 运行所有的测试(有时候只需要运行一个或一部分),发现新增的测试不能通过

③ 做一些小小的改动,尽快地让测试程序可运行,为此可以在程序中使用一些不合情理的方法

④ 运行所有的测试,并且全部通过

⑤ 重构代码,以消除重复设计,优化设计结构

简单来说,就是不可运行/可运行/重构——这正是测试驱动开发的口号。

一个生动比喻

举个比较生动的例子,这个例子你一定已经在很多关于TDD的文献资料上都看到过,但它确实是一个不错的比喻。在此我进行了一些加工和扩展。

盖房子的时候,工人师傅砌墙,会先用桩子拉上线,以使砖能够垒的笔直,因为垒砖的时候都是以这根线为基准的。TDD就像这样,先写测试代码,就像工人师傅先用桩子拉上线,然后编码的时候以此为基准,只编写符合这个测试的功能代码。

而一个新手或菜鸟级的小师傅,却可能不知道拉线,而是直接把砖往上垒,垒了一些之后再看是否笔直,这时候可能会用一根线,量一下砌好的墙是否笔直,如果不直再进行校正,敲敲打打。使用传统的软件开发过程就像这样,我们先编码,编码完成之后才写测试程序,以此检验已写的代码是否正确,如果有错误再一点点修改。

你是希望先砌墙再拉线,还是希望先拉线再砌墙呢?如果你喜欢前者,那就算了,而如果你喜欢后者,那就转入TDD阵营吧!详细可参阅。

本质和优势

或许只有了解了测试驱动开发的本质和优势之后,你才会领略到她的无穷魅力。 测试驱动开发不是一种测试技术,它是一种分析技术、设计技术,更是一种组织所有开发活动的技术。相对于传统的结构化开发过程方法,它具有以下优势:

1) TDD根据客户需求编写测试用例,对功能的过程和接口都进行了设计,而且这种从使用者角度对代码进行的设计通常更符合后期开发的需求。因为关注用户反馈,可以及时响应需求变更,同时因为从使用者角度出发的简单设计,也可以更快地适应变化。

2) 出于易测试和测试独立性的要求,将促使我们实现松耦合的设计,并更多地依赖于接口而非具体的类,提高系统的可扩展性和抗变性。而且TDD明显地缩短了设计决策的反馈循环,使我们几秒或几分钟之内就能获得反馈。

3) 将测试工作提到编码之前,并频繁地运行所有测试,可以尽量地避免和尽早地发现错误,极大地降低了后续测试及修复的成本,提高了代码的质量。在测试的保护下,不断重构代码,以消除重复设计,优化设计结构,提高了代码的重用性,从而提高了软件产品的质量。

4) TDD提供了持续的回归测试,使我们拥有重构的勇气,因为代码的改动导致系统其他部分产生任何异常,测试都会立刻通知我们。完整的测试会帮助我们持续地跟踪整个系统的状态,因此我们就不需要担心会产生什么不可预知的副作用了。

5) TDD所产生的单元测试代码就是最完美的开发者文档,它们展示了所有的API该如何使用以及是如何运作的,而且它们与工作代码保持同步,永远是最新的。

6) TDD可以减轻压力、降低忧虑、提高我们对代码的信心、使我们拥有重构的勇气,这些都是快乐工作的重要前提。

7)快速的提高了开发效率

现状和前景

测试驱动开发的技术已得到越来越广泛的重视,但由于发展时间不长,相关应用并不是很成熟。现今越来越多的公司都在尝试实践测试驱动开发,但由于测试驱动开发对开发人员要求比较高,更与开发人员的传统思维习惯相违背,因此实践起来有一定困难。 美国不少著名软件公司如IBM很早就开始向敏捷转型,在此过程中,TDD通常是最重要也最艰难的一个,正如IBM开发转型部门副总裁Sue Mckinney所言:测试驱动开发前景非常诱人,但是“在这个过程中我们的付出可能也是最多的。”Forrester的高级分析师Dave West认为,测试驱动开发(TDD)就像是“圣杯”,但是“如果能达到这个目标,付出再多的辛苦也是值得的。”

我想,测试驱动开发的推广过程中,首要的问题是将开发人员长期以来形成的思维观念和意识形态转变过来,开发人员只喜欢编码,不喜欢测试,更无法理解为什么没有产品代码的时候就先写单元测试;其次是相关的技术支持,测试驱动开发对开发人员提出了更高的要求,不仅要掌握测试和重构,还要懂得设计模式等设计方面的知识。

正像每种革命性的产物刚刚产生之初所必然要经历的艰难历程,测试驱动开发也正在经历着,但她正在逐渐走向成熟,前途一片光明。相信未来几年内,国内的一定会越来越多的软件企业开始普及测试驱动开发。

关键词:敏捷开发,测试驱动开发

 

DEVOPS基础

DevOps是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。它的出现是由于软件行业日益清晰地认识到:为了按时交付软件产品和服务,开发和运营工作必须紧密合作。

可以把DevOps看作开发(软件工程)、技术运营和质量保障(QA)三者的交集
传统的软件组织将开发、IT运营和质量保障设为各自分离的部门。在这种环境下如何采用新的开发方法(例如敏捷软件开发),这是一个重要的课题:按照从前的工作方式,开发和部署不需要IT支持或者QA深入的、跨部门的支持,而现在却需要极其紧密的多部门协作。然而DevOps考虑的还不止是软件部署。它是一套针对这几个部门间沟通与协作问题的流程和方法。
需要频繁交付的企业可能更需要对DevOps有一个大致的了解。Flickr发展了自己的DevOps能力,使之能够支撑业务部门“每天部署10次”的要求[7]──如果一个组织要生产面向多种用户、具备多样功能的应用程序,其部署周期必然会很短。这种能力也被称为持续部署[8],并且经常与精益创业方法联系起来。[9] 从2009年起,相关的工作组、专业组织和博客快速涌现.

DevOps的引入能对产品交付、测试、功能开发和维护(包括──曾经罕见但如今已屡见不鲜的──“热补丁”)起到意义深远的影响。在缺乏DevOps能力的组织中,开发与运营之间存在着信息“鸿沟”──例如运营人员要求更好的可靠性和安全性,开发人员则希望基础设施响应更快,而业务用户的需求则是更快地将更多的特性发布给最终用户使用。这种信息鸿沟就是最常出问题的地方。
以下几方面因素可能促使一个组织引入DevOps:
1. 使用敏捷开发或其他软件开发过程与方法
2. 业务负责人要求加快产品交付的速率
3. 虚拟化[14]和云计算基础设施(可能来自内部或外部供应商)日益普遍
4. 数据中心自动化技术[15]和配置管理工具的普及
5. 有一种观点认为,目前占主导地位的“传统”美国式管理风格(“斯隆模型 vs 丰田模型”)[16]会导致“烟囱式自动化”,从而造成开发与运营之间的鸿沟,因此需要DevOps能力来克服由此引发的问题。
DevOps经常被描述为“开发团队与运营团队之间更具协作性、更高效的关系”。由于团队间协作关系的改善,整个组织的效率因此得到提升,伴随频繁变化而来的生产环境的风险也能得到降低。
DevOps对应用程序发布的影响
在很多企业中,应用程序发布是一项涉及多个团队、压力很大、风险很高的活动。然而在具备DevOps能力的组织中,应用程序发布的风险很低,原因如下:

与传统开发方法那种大规模的、不频繁的发布(通常以“季度”或“年”为单位)相比,敏捷方法大大提升了发布频率(通常以“天”或“周”为单位)
减少变更范围
与传统的瀑布式开发模型相比,采用敏捷开发或迭代式开发意味着更频繁的发布、每次发布包含的变化更少。由于部署经常进行,因此每次部署不会对生产系统造成巨大影响,应用程序会以平滑的速率逐渐生长。
加强发布协调
靠强有力的发布协调人来弥合开发与运营之间的技能鸿沟和沟通鸿沟;采用电子数据表、电话会议、即时消息、企业门户(wiki、sharepoint)等协作工具来确保所有相关人员理解变更的内容并全力合作。
自动化
强大的部署自动化手段确保部署任务的可重复性、减少部署出错的可能性。

现状
很多组织将开发和和系统管理划分成不同的部门。开发部门的驱动力通常是“频繁交付新特性”,而运营部门则更关注IT服务的可靠性和IT成本投入的效率。两者目标的不匹配,就在开发与运营部门之间造成了鸿沟,从而减慢了IT交付业务价值的速度。
• 开发人员经常不考虑自己写的代码会对运营造成什么影响。他们在交付代码之前,并不邀请运营人员参与架构决策或代码评审。
• 开发人员对配置或环境进行修改之后,经常没有及时与运营人员沟通,导致新的代码不能运行。
o 开发人员在自己的机器上手工修改配置,而没有记录所有需要的步骤。想找到必要的配置参数,通常需要尝试很多不同的参数;在得到一个可工作的状态后,往往很难识别出通过哪些最小步骤就能到达该状态。
o 开发人员倾向于使用有利于快速开发的工具:对代码修改更快的反馈,更低的内存消耗,等等。这样的工具集与运营人员面对的目标运行时环境非常不同:后者对稳定性和性能的要求远胜于灵活性。
o 由于开发人员平时使用桌面电脑,他们倾向于使用为桌面用户优化的操作系统。生产环境的运行时系统通常都运行服务器操作系统上。
o 在开发过程中,系统在开发者的本地机器上运行。在运营过程中,系统经常分布在多台服务器上,例如web服务器、应用服务器、数据库服务器等等。
• 开发是由功能性需求(通常与业务需求直接相关)驱动的。
• 运营是由非功能性需求(例如可获得性、可靠性、性能等)驱动的。
o 运营人员希望尽量避免修改功能,从而降低满足非功能性需求的风险
o 如果拒绝了小的修改,但给定时间段内需要修改的总量不变,那么每次变更的规模就会变大
o 变更规模越大,风险也越大,因为其中涉及的区域越多
• 由于运营人员尝试避免变更,新功能流入生产环境的速度因此被延缓,从而延缓了开发人员将特性交付给用户使用的速度。
• 运营人员可能对应用程序内部缺乏了解,从而难以正确地选择运行时环境和发布流程。
• 开发人员可能对运行时环境缺乏了解,从而难以正确地对代码进行调整。
诉求
• 更小、更频繁的变更──意味着更少的风险
• 让开发人员更多地控制生产环境
• 更多地以应用程序为中心来理解基础设施
• 定义简洁明了的流程
• 尽可能地自动化
• 促成开发与运营的协作
一般而言,当企业希望将原本笨重的开发与运营之间的工作移交过程变得流畅无碍,他们通常会遇到以下三类问题:
发布管理问题
很多企业有发布管理问题。他们需要更好的发布计划方法,而不止是一份共享的电子数据表。他们需要清晰了解发布的风险、依赖、各阶段的入口条件,并确保各个角色遵守既定流程行事。
发布/部署协调问题
有发布/部署协调问题的团队需要关注发布/部署过程中的执行。他们需要更好地跟踪发布状态、更快地将问题上升、严格执行流程控制和细粒度的报表。
发布/部署自动化问题
这些企业通常有一些自动化工具,但他们还需要以更灵活的方式来管理和驱动自动化工作──不必要将所有手工操作都在命令行中加以自动化。理想情况下,自动化工具应该能够在非生产环境下由非运营人员使用。
要开始优化发布流程,可以从问题识别开始:看看上面提到的哪种问题在你的团队中具有最高的优先级。
发布协调人
这是企业级IT组织中一个新出现的角色,其主要任务就是协调安排将企业级软件部署到预生产环境。对发布协调人的需求来自于以下几方面原因:
1. 需要弥合开发与运营的鸿沟
2. 基础设施日益变得复杂:为了运营web应用,需要多层基础设施和多种平台
3. 发布频率上升(由于敏捷开发和迭代式开发的引入)
4. 分布式团队:位于全球多个地点的、包含外包人员的、混合开发/测试/基础设施的团队
发布协调人的角色(也被称为部署协调人或集成协调人)源自发布管理或发布工程团队。这个角色与航空交通管制有些类似──实时协调不同团队的行动,有效使用共享的资源(空域、航道、跑道、航站门),达到组织的总体目标(安全起降)。
传统意义上的发布管理往往只关注软件变更的计划与管理,发布协调则需要控制“将特定软件变更发布至生产环境”的整个过程。这项工作需要系统地管理所有与“将代码构建并部署到生产环境”相关的技术任务,也被称为“发布工程”。
变更管理是跟踪企业IT环境中各种变化──不管是应用程序还是基础设施的变化──的基本原则。变更管理是ITIL v3的核心之一。

关键词:敏捷开发,DevOps

 

精益创业

概念

精益创业(Lean Startup)是硅谷流行的一种创新方法论。它的核心思想是,先在市场中投入一个极简的原型产品,然后通过不断的学习和有价值的用户反馈,对产品进行快速迭代优化,以期适应市场。

由来

精益创业(Lean Startup)由硅谷创业家Eric Rise2012年8月在其著作《精益创业》一书中首度提出。但其核心思想受到了另一位硅谷创业专家Steve Garry Blank的《四步创业法》中“客户开发”方式的很大影响,后者也为精益创业提供了很多精彩指点和案例。

很多IT从业人员在了解精益创业后认为,其核心理念可以追溯到软件行业的敏捷开发管理。例如“最小可用品”与“原型建模”非常相似,都追求快速的版本迭代,以及时刻保持与客户的接触并获得反馈等等,精益创业可以理解为敏捷开发模式的一种延续。

三大法宝编辑

从《精益创业》一书中提到的主要思路和脉络,结合在现实中使用的频率,精益创业提到的三个主要工具是:“最小可用品”、“客户反馈”、“快速迭代”。

最小可用品–是指将创业者或者新产品的创意用最简洁的方式开发出来,可能是产品界面,也可以是能够交互操作的胚胎原型。它的好处是能够直观的被客户感知到,有助于激发客户的意见。通常最小可用品有四个特点:体现了项目创意、能够测试和演示、功能极简、开发成本最低甚至是零成本。

客户反馈–是指通过直接或间接的方式,从最终用户那里获取针对该产品的意见。通过客户反馈渠道了解关键信息,包括:客户对产品的整体感觉、客户并不喜欢/并不需要的功能点、客户认为需要添加的新功能点、客户认为某些功能点应该改变的实现方式等;获得客户反馈的方式主要是现场使用、实地观察。对于精益创业者而言,一切活动都是围绕客户而进行,产品开发中的所有决策权都交给用户,因此,如果没有足够多的客户反馈,就不能称为精益创业。

快速迭代–是针对客户反馈意见以最快的速度进行调整,融合到新的版本中。对于互联网时代而言,速度比质量更重要,客户需求快速变化,因此,不追求一次性满足客户的需求,而是通过一次又一次的迭代不断让产品的功能丰满。所以,才会有微信在第一年发布了15个版本,扣扣保镖3周上线的记录。

常用方法编辑

1. 精简式反馈

大多数团队认为,只有开发出一个功能完整、看起来很美观的界面之后,才能将其展示给客户以获得反馈。事实证明,只要将一些简单的模型功能组织在一起,并提供可点击的区域,同样可以获得有价值的反馈。事实反复证明,消费者十分愿意与这些可点击的功能互动,就好像它们是最终的产品。这可以帮助创业公司了解其设计是否有效,在真正进行大规模开发工程之前,这是一个十分伟大的方法。

2. 客户采访

不要闭门造车,而要通过收集数据来支持产品设计。具体而言,要走出去,找到自己产品的潜在客户,通过与他们交流来找到解决问题的答案。对于该方法,开发者也许已经听过上百次了,并且也认可,但要真正把它培养成习惯并不容易。

3. 以小见大

要想迅速了解消费者是否喜欢一项新功能,只需通过推出该功能的一小部分即可。产品定制创业公司CustomMade就是如此,开发者希望让访问者借鉴他人的项目来获得灵感。但没有必要费力地开发出整个功能,因此仅推出了第一个按钮。当开发者看到大量访问者点击该按钮时,就知道应该把这一功能继续完成。经过调整和优化,用户互动明显提升。

4. 判断

开发者可以将竞争对手的产品看作是一个免费的原型。观察消费者如何使用这些产品,他们喜欢哪些功能,哪些功能用不到,甚至令人厌恶。了解这些,开发者在进行产品设计、营销和销售时就会做出更好的决定。

5. 微调查

精益创业人士需要使用一项有效的调查模式,尽量让调查与当前的研究内容紧密结合。例如,如果想知道顾客为何选择企业的一项定价计划,就可以给出一个小的弹出式调查问卷,而不是可能需要几天后才能看到的电子邮件。

此外,阅读100个简短的用户反馈获得的内容远比知道32%的人选“B”更多。

6. 真正数据原型

当为优惠券网站RetailMeNot设计优惠券页面时,设计者需要真正的优惠券数据来评估设计。设计者花费了两天时间来创建原型,尽管还有不少问题,也不具备太多功能,但却可以从消费者那里获得许多有价值的反馈。

反馈发现,最初约50%的想法不合理。后来又重复了三次,建立原型并展示给消费者,最终使创新的设计更具可用性,点入率显著提升。

7. 实地考察

最初,某个项目组与Foundation Medicine合作来完善其临床肿瘤基因组学报告。因此项目组决定参观一下肿瘤中心,观察医生是如何使用报告的。后来发现,他们努力设计出的报告通常是通过传真来接收的,小字体很难看清,各种颜色信息也是多余的。尽管这是一个很容易解决的问题,但只要到了现场才能发现问题。

优点编辑

一是快速,精益创业模式下,所有的创新行为和想法都必须在最短的时间呈现出来,抛弃一切暂不重要其他功能,把极简的功能展现给客户,无论成功或失败,都能够以最快的速度知道结果。

二是低成本,过往“十年磨一剑”式的长期研发,其最终成果推出后,有可能发现花费了大量人力、物力和时间所开发出的产品,并不是客户所需要的。这种巨大的浪费除了会给创业者、企业带来绝大的经济损失之外,还对团队的士气形成巨大打击,不少团队成员会纷纷出走。而精益创业所采用的“频繁验证并修改”的策略,确保不会在客户认可之前投入过高的成本。

三是高成功率,虽然创新充满风险,成功系数低,但也不是没有套路可遵循。按照精益创业的模式,从“最小可用品”出发,过程中每一次迭代都可以寻找客户进行试用,了解客户对产品的看法,寻找产品的不足和客户希望增加乃至修改的功能点。当一路上持续遵循客户的意见进行开发后,项目组的不断纠偏的成果就是产品越来越符合客户想要的效果,而不是开发团队闭门想象的样子。通过持续的“测试–调整”以及快速迭代,创新的成功率能够大大提升。

适用范围编辑

精益创业来源于互联网行业,是软件开发的一种新模式。但其背后的“客户验证”思想在大量非IT领域得到应用。例如美剧的拍摄,往往都会先拍摄一部几十分钟的先导片,交代主要的人物关系、矛盾冲突、故事背景,然后邀请几十位观众参加小规模试映会,再根据观众的反馈来决定剧情要作那些修改,是否需要调整演员,以及决定是否投拍。在每一季结束时,制作方又会根据收视率和观众意见,决策是砍掉该剧还是订购新一季内容。这种周拍季播的模式,把所有的决策权交给观众,让制作方的投资以及失败成本降到了最低,是一种典型的精益创业方式。

整体而言,精益创业适合客户需求变化快、但开发难度不高的领域,比如软件、电影电视、金融服务等领域。在国内,除互联网企业外,酒店管理领域的“今夜酒店特价”就采用这种小步试错的方式进行开发,一些传统企业如中信银行信用卡中心利用精益创业进行信用卡产品及客户服务的创新,并把三大法宝固化到项目管理机制中。

由于精益创业需要经常进行客户验证,因此对于一些客户验证成本较高、或者技术实现难度较大的工作并不适合。比如大型赛事,服务客户是全体运动员,但想要获得他们的频繁反馈是比较困难的。又比如航天工程,客户需求是比较明确、清晰的,主要难点在于飞行器的技术实现和对接控制。

关键词:敏捷开发,精益创业

 

MARTIN FOWLER谈敏捷开发

每个人都在谈论敏捷开发(Agile Development)。但是,你是否选择了正确的方法学?你所选的方法是否正常运转?你是否应该请求顾问的帮助?你应该如何管理开发的过程?还有,如何修补那些“先天不足”的代码?轻量级方法学的大师Martin Fowler 将回答这些问题。

应该问什么?

记者:在寻找适合自己团队的方法学时,开发经理应该提怎样的问题?

Fowler:首先,他们需要 对自己的项目有一个充分的了解。他们需要了解项目中主要的风险,同时应该了解企业的文化和涉及此项目的团队成员。我一直都认为:你应该选择适合于团队的方 法学,而不是相反。实际上,“敏捷宣言”的主要规则之一就是:个人之间的交流比过程、工具更重要。团队中的个人以及这些个人协同工作的方式,这是项目成功 的一个重要因素,比对过程和工具的选择要重要得多。

记者:回到前面那个问题。第一件应该问的就是:“你所做的是什么项目?”是这样吗?

Fowler:准确地说,应该 是“你所做的是什么类型的项目”。涉及上百人的航空软件项目和只涉及六个人的网站项目,它们采用的方法学肯定是不一样的。曾经有一个人跟我谈起他的工作。 以前他认为由小变大是一个困难的过程,但是后来他发现由大变小也同样困难。大型项目所选择的方法学对于小型项目通常就不适用了。另外,软件产品的类型也是 影响因素之一。嵌入式系统和商用软件,它们采用的方法学肯定也是不同的——这有一点猜测的成分,因为我从来没有开发过嵌入式系统,只开发过商用软件。

记者:你刚才还提到,开发经理应该了解他们可能遇到的风险?

Fowler:是的,开发经理 必须知道哪些因素可能导致项目失败。例如,敏捷社群一直关注的一个重要问题就是需求的易变性。如果需求不确定、无法将需求固定在某个合理的层面上,那么选 择敏捷开发方法就会比较合适。传统的软件工程方法总是要求你将需求固定住,并且在后续过程中不再变化。因此,需求的易变性就会成为一个重要的风险源。我认为, 这种风险对于“是否选择敏捷方法”起着决定性的作用。

记者:你刚才提到的第三点是“企业或者开发团队的文化”。你好象认为这比方法学本身还要重要,为什么?

Fowler:很明显,如果我 能有一打顶级的程序员,而他们又能很好地合作,我就会让他们自己去尽情发挥。这时,使用什么过程根本就无所谓,因为他们的天才一定会让我们胜出。这是我们 这一行中的一个决定性因素:如果优秀的人能很好地合作,那么他们一定比普通团队做得更好,因为他们自己就会找到最适合他们的工作方式。实际上,这也是敏捷开发过程中的一个非常重要的概念。OTI 的Dave Thomas说,这个世界上有两种开发者:适合他的和不适合他的。他的方法学就是:雇佣那些适合他的人。这正是OTI 之所以获得成功的重要因素之一。

记者:假如你的公司里没有一个真正意义上的“明星程序员”,而只有一些不那么出色的、需要大量管理工作才能保证代码质量的程序员,你会怎么办呢?你有什么办法弥补人员上的缺憾吗?或者你要把他们全都解雇掉,然后再从头开始?

Fowler:呵呵,如果可行 的话,我就会把他们解雇掉,然后重新雇一批聪明的人来。不过,这通常都不可行,你必须充分利用手上的资源。你必须认识到:即使没有一批天才,只要让一批庸 才很好地合作,也能获得很好的效果。而作为经理,你应该做的就是:给没有良好传统的团队灌输一个合适的过程。同时,对于个人能力不那么突出的团队,我会非 常重视提高他们的能力。如果你能提高他们的个人能力,那么你也能获得更多的优势。不过,这并不意味着我要放弃过程的引入。

记者:现在,开发经理已经知道自己要开发的是什么样的项目,也知道项目的主要风险所在,对企业文化也有了足够的了解。那么,他应该如何借助这些信息来指导他的团队选择正确的方法学呢?

Fowler:在了解了 这些情况之后,就应该去阅读各种不同的方法学,并拿你拥有的这些信息去和这些方法学的约束条件作匹配,从中做一个最佳选择。然后,让你的团队实施所选的过 程,并坚持几个月。注意:应该完全按照这种方法学所说的去做,哪怕它所说的听起来并不是一个好主意,也照着它去做。我看到很多人选择一种方法学,却不照着 它所说的做。这是一个非常严重的问题。比如说,在极限编程(Extreme Programming,XP)的典型情况下,人们会说:“我们想要进行极限编程,不过不想采用其中‘测试’那一部分。”当然了,如果你不按照XP 的要求那样进行严格的测试,整个过程都会失败。因此,你应该根据自己的经验来判断哪种方法学适合于你,然后全力以赴地实施它。这是敏捷开发的一项重要原则。

何时寻求帮助?

记者:假设一个开发团队已经提出了恰当的问题,挑选了一种方法学,并且开始尝试⋯⋯但还是遇到了困难。开发团队应该在什么时候寻求外部的帮助呢?

Fowler(笑):我的公司从事大量的顾问工作,恐怕我的答案会有个人因素吧?正如我前面说过的,经验丰富的、聪明的、优秀的程序员,他们总是能干出卓著的成效。因此,引进一些好的经验和一些好的建议总是会有所帮助的。

记者:外部的帮助对开发团队有什么好处?

Fowler:有几种不同的方 式。很多干这一行的人采用的都是“导师制”的方式:从团队之外带来一个人,让他作为整个团队的导师。这个人要成为项目组的一员,并且确实做一些开发工作, 但他的主要职责是指导其他人。显然,如果你涉足一个比较新的领域,导师制会是一个不错的选择。我们在ThoughtWorks 采用的方式则是所谓的“合作制”:开发团队中大约1/3 甚至1/2 的人来自顾问方。这些人有两件事要做。首先,他们帮助项目获得成功;同时,他们还要教给其他人如何工作。合作制的好处在于:顾问能更好地理解团队的工作, 团队的成员也能获得更合理的指导,并从中学到更多的东西。

记者:哪些迹象表示团队需要帮助呢?

Fowler:哦,我是 坚定不移地相信迭代式开发的,也就是说,我们应该在每次迭代结束时都发布有商业价值的代码。如果你发现某次迭代发布的东西不够多,或者发布的质量不够好, 这就意味着你遇到困难了。此时,你就应该寻求帮助。的确,迭代式开发很有价值。比起瀑布式开发,迭代式开发能让你更好地跟踪项目的进度。开发者可以管理自 己吗?

记者:能不能让开发者自己管理自己?或者,在什么时候需要专门让一个人来管理开发者?

Fowler:呃,这个 问题的答案取决于你如何看待“管理”这个词。任何一个团队中都有非常重要的管理者:他们帮助人们分工协作,他们保持团队中、团队与外部良好的人际关系。这 些东西,从传统角度来看并不属于“管理”的范畴,但这的确是管理者的责任。为了进入软件开发这个行业,你必须有一定的才华。我是说,在软件开发者这个圈子 里,哪怕比较差的那一部分,他们也是相当聪明的。只有那些才华横溢的人才可能出人头地。所以,我一直都认为:软件开发是一项专业工作,正如律师、医生的工 作是专业工作一样。而软件开发者,他们所做的是专家的工作,也应该得到专家的待遇。你不可能让一个普通行业的管理者到律师事务所去教这些律师怎么工作,也 不可能让一个非医学专业的人到诊所去教医生如何治疗病人。同样,你也不应该让一个没有技术背景的人去指挥程序员、设计师们的工作细节。因此,管理很重要, 但我们所说的这种“管理”和大多数人所理解的“管理”根本不是一回事。

记者:那么,管理者应该做什么呢?

Fowler:呃⋯⋯创造一个良好的环境,让所有人能齐心协力解决问题。然后,保证团队所有成员都能顺畅地彼此交流。我见过一位非常优秀的经理,他就很善于促进团队成员之间的交流。在他的团队中,每个人都知道项目的进展情况,成员能够很好地协作解决问题。

重构适用于什么地方?

记者:你可以算得上是“重构之父”了。重构似乎在很多方法学中都适用。你对于重构的定义是怎样的?

Fowler:重构(refactoring)是这样的一种技术:在不对代码的功能特征作任何改变的前提下,修改现存代码的结构,以提高设计的质量。

记者:你认为重构适用于开发过程的什么地方?

Fowler: 人们通常会在两个地方使用重构。最显而易见的就是:当你接手一块设计质量不高的代码时,你可能想要改进它,因此就需要使用重构。如果代码的设计质量很糟 糕,那么新功能的添加和错误的修复都会非常困难。但是你又不愿意从头开始重新编写整个软件,因为工作量太大。这时,重构就给了你第三种选择:你可以借助这 一系列技术有条不紊地逐步改进软件的结构。对于重构的第二种用法则是在XP 项目中的那种方式。在进行极限编程时,你会持续不断地使用重构。每天你都会对自己写下的代码做一些重构。所以,每当你要开始一个新任务时,你就会看着以前 的代码说:“这些代码能让我轻松地加入这项新的功能吗?”如果不行,你就会重构它,使得新功能的加入更容易。在努力让测试能够通过的过程中,你可能并不太 关心设计的质量,而只是关心如何实现功能;但是,一旦测试能够顺利通过,你就必须进行重构,将设计质量提高。总之,在进行极限编程时,你会持续不断地对代 码进行重构,以保证设计质量不会降低。因此,这种方式与前面所说的“处理遗留代码”的方式有所不同。不过,如果你成功地通过重构将遗留代码的质量提升到了 一个相当高的标准上,那么你应该会采用XP 的风格进行后续的开发。

记者:除了XP 之外,重构还适用于别的方法学吗?

Fowler: 重构适用于任何方法学。只要你现有代码的设计质量不合你的要求,你就应该考虑重构它。不过,如果有一整套自动化测试的支持,那么重构会更有保障,因为自动 化的测试是重构的一个重要的前提条件。如果你无法使用自动化重构工具的话,至少要有自动化的测试。有很多人在瀑布式的开发中也成功地使用了重构。所以,只 要你希望改进代码的质量,重构就是值得考虑的技术。

记者:有没有哪种方法学不鼓励重构呢?

Fowler:我想,的确有一些方法学试图降低对重构的需要。基于工程的方法学的核心思想就是:在写任何一行代码之前,你必须先完成整个设计。这种思想认为:如果你的设计做得正确无误,你就不需要重构,因为代码质量一定是非常高的。当然,实际上很难把设计做得那么好。

记者:既要让开发者有重构的自由,又不能失去对代码和配置的控制,开发经理要如何应对这种矛盾呢?

Fowler: 重构与代码的所有权并不矛盾。不过,在那种强调代码所有权的方法学中,的确难以进行重构。在我看来,代码的所有权大抵有三种形式:强所有权、弱所有权、以 及集体代码所有权。XP 鼓励的是集体代码所有权,有人认为这是“没有代码所有权”,但实际上这意味着“所有人拥有所有代码”——任何人都可以在任何时候修改任何一部分的代码。之 所以将它称为“集体代码所有权”而不是“无代码所有权”,是因为团队作为一个整体负责保证所有代码的质量,因此代码就是集体所有的。“强代码所有权”则是 另一个极端:这种模型将代码分成几大块,交给每个开发者一块,每个开发者只能修改自己的那一块代码。而在“弱代码所有权”的模型中,仍然需要将代码分成 块,并分配到人,每个人负责确保自己那一部分代码的设计质量。但是,如果有需要,其他人可以来修改他负责的代码。这也可以看作是与代码的拥有者之间的某种 合作关系。可以看出,强代码所有权的开发模式并没有阻止开发者进行重构,但在这种模式下重构的确会变得困难。一个典型的例子就是给方法改名:你的代码中有 一个方法,它的名称不能很好地描述它的用途,因此你希望将它改名,给它起一个更具有描述能力的名称。但是,如果你的团队采用了强代码所有权的开发模式,而 你想要改名的又是一个公开的方法,你就必须费很大的力气才能完成这次改名。因为这个方法可能被很多其他的地方调用到,而那些调用它的代码可能是由其他人来 拥有的。在这种情况下,你必须将改名之前的旧方法标记为“不推荐使用”,并使其调用改名后的新方法。这会大大降低你的效率,并且让你感到非常烦躁。而在弱 代码所有权的模式下,你也许就完全可以直接修改那个方法的名称,并修改它所有的调用者。这并不是说没有人对其他的代码负责,只不过他们可以给你一定程度的 方便,让你完成你的修改。如果你使用了自动化重构工具的话,这样的方便就尤其重要了——在这种工具中,给一个方法改名只需要点击一个按钮并输入新的名称就 行了。如果要选择弱代码所有权或者集体代码所有权的开发模式,就必须同时选择一个同步控制系统来进行源码控制。CVS 就是这样的一个系统,它允许多人同时更新同一块代码,并通过冲突检测等技术来保证不会把事情搞乱。

要不要敏捷开发?

记者:什么时候不应该使用敏捷开发?

Fowler:当你能获得固定不变的需求时。如果你知道需求是固定不变的,你也了解自己要使用的技术,对于开发团队的能力也很清楚,那么传统的软件工程方法会更合适。

记者:你遇到过这种时候吗?

Fowler: 呵呵,问题就在这里,不是吗?实际上,我们总是遇到无法确定的需求。那么,你要怎么面对这些变化不定的需求?敏捷开发者们说:好吧,让我们假设“无法确定 的需求”是随时都存在的,并提出一种能够包容它的开发过程——实际上,还不仅仅是包容,而是欢迎这种不确定性。传统的软件工程方法教我们如何将需求固定下 来。Alan Cooper、Larry Constantine 和Lucy Lockwood 所提倡的交互式设计方法很大程度上正是为了这个目的。有很多人从事于需求工程的工作,他们也是朝这个方向在努力。他们说:“我们要将需求固定下来。为了这 个目标,我们全力以赴。”但是,对于一个项目,你必须要判断它的需求是否天生就无法固定。如果有可能将需求固定,这样的开销是否值得?传统方法和敏捷开发方法,哪一种的性价比更高?说实话,我对这两者之间的权衡并没有太多的发言权,因为我几乎都没看到过有谁成功地将需求固定下来的。

关键词:敏捷开发

 

什么是结对编程

结对编程技术是一个非常简单和直观的概念:两位程序员肩并肩地坐在同一台电脑前合作完成同一个设计。同一个算法、同一段代码或同一组测试、与两位程序员各自独立工作相比.结对编程往往只需花费大约一半的时间就能编写出质量更高的代码, 但是,人与人之间的合作不是一件简单的事情——尤其当人们都早已习惯了独自工作的时候、实施结对编程技术将给软件项目的开发工作带来好处.只是这些好处必须经过缜密的思考和计划才能真正体现出来。而另一方面,两个有经验的人可能会发现配对编程里没有什么技能的转移,但是让他们在不同的抽象层次解决同一个问题会让他们更快地找到解决方案,而且错误更少。

结对编程还有其他多种好处:
1、直接的、连续的代码回顾。
2、与别人工作会增加责任和纪律性。
3、同时理解一个问题。
4、在有人盯着的时候去偷懒要困难得多!
两个程序员具有相同的缺点和盲点的可能性很小,所以我们当我们采用结对编程的时候会获得一个强大的解决方案。而这个解决方案恰恰是其它软件工程方法学中所没有的。
在我们平时的编程当中,如果遇到一个非常难解决的问题(困难到对该项目产生厌烦的态度),那么你势必会希望寻求帮助,无论是从信息量庞大的Internet网络里,还是从身边的技术大师里,你都会拼了老命去解决(前提是你有对计算机知识的势爱)。这个时候不妨采用结对编程试一下,其它的不说,可能感觉就不同。

关键词:敏捷开发,结对编程

 

0
0
小时
0
分钟
0
由Scrum.org主办的 2024中国Scrum大会 8月17日将在上海开幕
0
0
小时
0
分钟
0
预约回电
留下您的手机号,我们会在第一时间联系您。
热线电话:400-696-6280
预约回电
预约成功,我们会尽快联系您。