敏捷方法实践精要
20世纪90年代末产生了以Scrum与XP为代表的敏捷方法。敏捷方法吸收了历史上各种软件开发方法中的最佳实践,如迭代、原型、用户驱动、时间箱管理等,并提出了轻量化过程的思想,以简化开发过程中的管理负担,达到简洁高效的目的。
敏捷方法与以CMMI为代表的规范方法都是为了按时、保质地实现需求,殊途同归,目的相同,实现的方法不同。
两种方法都认为每个人都会犯错。
规范方法的管理假设是:通过遵循规范的过程可以降低犯错的概率。如何确保按过程执行了呢?需要QA进行检查。QA怎么检查呢?通过检查执行时留下的证据来验证是否遵循了过程。这些证据是否是最终用户所关注的呢?是否对最终用户有直接作用呢?未必!遵循过程的人员可能做了一些无用功,这些投入不是客户所关注的。
敏捷方法的管理假设是:开发人员是有经验、有智商的,不需要详细地告诉项目成员如何做一件事情,只要告诉项目成员做事的原则与目标,他们就可以自己根据经验判断应该如何做,应该如何实现目标,即使在过程中发生了错误,也能够及时地发现并纠正。在这种场景下,不需要保留做事的中间证据,只要检查半成品或成品的质量即可。胜任工作与互相协同的人是敏捷方法的核心基础。敏捷方法强调好的结果胜过好的过程,因而敏捷方法更注重过程的速效性。敏捷方法强调在产品本身投入更大的质量成本,而非在过程的监督与执行上。敏捷方法期望客户实时参与、开发人员实时面对面的沟通,以便于进行验证与确认。规范的方法强调文字沟通、强调记录。敏捷的方法强调口头的、面对面沟通。流行的敏捷方法大都回避了对于质量保证活动的描述,而是强调了测试,强调了实时地对文档进行评审。
如果说规范方法的管理假设是“人之初,性本恶”,敏捷方法的管理假设则是“人之初,性本善”。如果说规范方法是“中药”,敏捷方法则是“西药”。中药长于治本,重在预防,见效慢,效果持久。西药长于治标,见效快,立竿见影。
很多软件项目的管理者、开发者倾向于采用敏捷开发方法,但是不能误解敏捷方法。敏捷方法不意味着没有管理,也不意味着不写文档,不要打着敏捷的旗号行“不作为”之实,从而玷污了敏捷的名声,正如以机械的行为玷污CMMI的名声一样。
CMMI在实施初期往往编写了大量的文档,随着对CMMI的理解越来越深刻,与实际的结合越来越紧密,文档会越来越精简。
敏捷方法在初期时,往往感觉很简单,但是越做就会感觉越复杂,一个很简单的活动如果想做到位,有很多注意事项。
CMMI的实践如同白开水,没滋没味。敏捷的实践如同陈年老酒,需要慢慢品,越品越有味。
中药与西药都能治病,关键是看你得的什么病!只要对症下药,中西医结合可能更好!
Scrum敏捷项目管理
Scrum是一种敏捷的项目管理方法,该方法的名字源自于英式橄榄球争球的队形,该方法借鉴了橄榄球队成功的原则发展而来。Scrum将软件开发团队比拟成橄榄球队:
有明确的最高目标;
熟悉开发流程中所需具备的最佳典范与技术;
团队具有高度自主权;
成员紧密地沟通合作;
以高度弹性解决各种挑战;
确保每天、每个阶段都朝向目标有明确的推进。
Scrum将开发过程分为多个迭代,如图2-1所示每次迭代称为一次冲刺(Sprint),每个Sprint具有固定的时间长度,一般为2~4周。
首先,产品需求被分解成产品需求待办事项(Product Backlogs)。然后,在Sprint计划会议(Sprint Planning Meeting)上,最重要或者是最具价值的产品需求待办事项被优先安排到下一个Sprint周期中。同时,在Sprint计划会上,将会预先估计所有已经分配到Sprint周期中的产品需求待办事项的工作量,并对每个条目进行设计和任务分配。在Sprint开发过程中,开发团队每天都会进行一次简短的Scrum会议(Daily Scrum Meeting)。会议上,每个团队成员需要汇报各自的进展情况,同时提出目前遇到的各种障碍。每个Sprint周期结束后,都会有一个可以被使用的系统交付给客户,并进行Sprint评审会议(Sprint Review Meeting)。评审会上,开发团队将会向客户或最终用户演示新的系统功能。同时,客户会提出意见以及一些需求变化。这些可以以新的产品需求待办事项的形式保留下来,划分优先级,并在随后的Sprint周期中得以实现。Sprint回顾会随后会总结上次Sprint周期中有哪些不足需要改进,有哪些方面值得肯定。最后整个过程将从头开始,开始一个新的Sprint计划会议。

图2-1(此图片来自于网络:http://www.kuqin.com/upimg/allimg/100204/1436350.jpg)
Scrum 的3个角色
在Scrum方法中将项目的利益相关者分成两大类:Pigs角色与Chickens角色。Pigs即为项目组的实际参与人员,Chickens为项目组的外部人员,包括经理、最终用户等。这种分类的方法源自于一个关于猪和鸡合伙开餐馆的管理寓言(如图2-2所示):一天,一头猪和一只鸡相遇了,鸡对猪说:“嗨,我们合伙开一家餐馆怎么样?”猪说:“好主意啊,那你准备给餐馆起什么名字呢?”鸡想了想说:“叫‘火腿和鸡蛋’怎么样?”“那可不行”,猪说:“我把自己全搭进去了,而你只是参与而已。”Pigs在Scrum中细分为三个角色:Scrum Master、Product Owner、Team,这三个对等地位的角色构成一个平衡的铁三角,推动整个项目的进展。

图2-2 Scrum方法中的不同角色
1.Scrum Master
Scrum Master不是项目经理,他没有分配任务的权力,没有考核的权力,没有下命令的权力,他在项目组承担了如下细分角色。
(1) 会议主持人
他负责主持四个主要的会议:策划会议、每日站立会议、迭代评审会议、迭代回顾会议。
(2)牧羊犬
他负责屏蔽项目组外部的干扰。

图2-3 屏蔽干扰
(3)雷锋
他给Product Owner、Team提供帮助,帮助Product Owner确定需求、排定优先级,帮助Team做估算、分解任务、完成任务。
(4)外交官
当项目组外部有人不理解项目组的工作时,他负责去解释说明,负责对外发布项目组的信息。
(5)教练
他指导项目成员按照Scrum的原则、方法做事情,当出现偏差时,他去纠正,可以说他既是精神教父,也是警察(QA)。如果有项目成员不熟悉Scrum的方法,他要去提供相关的培训。
(6)清道夫
他负责排除在项目进展中遇到的各种障碍,如果他没有能力或没有资源他可以协调项目组的其他成员一起来排除障碍。
Scrum Master并非固定地由一个人承担,在一个团队中,有能力的、熟悉Scrum的成员都可以担当Scrum Master。
敏捷方法看上去简单,实施起来比较难。敏捷方法的实践少,但是要求每条实践必须做到位,做扎实。真要做到位就要求Scrum Master必须很熟悉Scrum的基本原则与基本思想。简单的站立会议,有些Scrum Master就不能控制局面,一提到问题就讨论如何解决问题。可以写一个站立会议的检查单,在开站立会议前的1分钟,把站立会议的要点重复一遍,慢慢地把这些思想渗透到每个人的骨髓中。
所以,对于Scrum Master而言要培养其基本的技能:如何主持会议?不仅仅要理解Scrum的要求,而且要具备这些技能。公司里熟悉Scrum方法的人可以作为Scrum Master的导师,旁观Scrum Master的活动,然后指出其缺点,在实践中指导提升其基本技能。项目成员也要重视每次迭代结束时的回顾活动,通过自我总结提高团队的整体能力。Scrum Master并非固定的,是可以变化的,通过这种方式也可以发现团队中适合做Scrum Master的人。有的团队每天站立会议的主持人是变化的,大家轮流主持,这也是一种很好的尝试,通过这种方法可以发现人才。
挑选什么样的人做Scrum Master?要选组织能力强的人,而不一定是选择技术能力强的人,Scrum Master的作用是要发挥整个团队的能力,激发大家的能力。不是Scrum Master有多强,而是整个团队有多强!
2.Product Owner
Product Owner是产品的负责人,或者是需求的负责人, 他在项目组承担了如下细分角色。
(1)领域专家
他是需求方面的专家,熟悉需求。他知道客户、最终用户以及其他利益相关者对项目的真正需求是什么。他负责编写用户需求,维护用户需求。
(2)需求决策人
哪个需求重要,哪个需求不重要,需求的优先级如何排列,在某次发布中要发布哪些需求都由他来拍板。他负责平衡需求、进度与资源的关系。
(3)需求讲师
他负责在项目进展过程中给项目组的其他成员讲解需求的含义,对需求进行答疑。
(4)测试员
他负责编写每个需求的验收标准、功能测试用例。
(5)验收人
当项目成员完成某个需求后,是Product Owner进行功能测试和验收,他认可后才能认为某个需求完成了。
Product Owner可以来自于用户、客户、销售部、产品策划部门,或者来自于开发部门的需求分析人员。无论是来自哪里,都需要满足如下的要求。
Collaborative:易于协作、易于沟通。
Representative:有代表性的,能代表用户、客户、市场的利益。
Authorized:有授权,得到了用户、客户、市场等的授权,有对需求的决策权。
Committed:尽责,能够认真地、尽职尽责地工作。
Knowledgeable:在行,明白,熟悉需求。
以上的5项要求可以简写为CRACK,这是我们的理想,在现实中找这样的Product Owner有一定的难度。
Product Owner是一个角色,并非指是一个人,可以是多个人。但是如果是多个人,这多个人要协调一致,对需求的理解与解释是一致的。
根据我观察在多家软件公司中实施Scrum方法的成功与失败经验,PO这个角色是最容易失败的角色。熟悉需求而又有决策权的人往往很忙,不能全程参与开发,因而无法保证与项目组的沟通时间,无法落实其测试与验收的职责。如果请多个人分担此角色,则又存在与真正的PO之间保持沟通一致的问题。
3.团队成员
Team Member是技术的责任人,他们负责实现这个系统,他们是自我管理的,不需要外部的管理者来管理他们。在一个Scrum团队中,一般是整个团队(包含Product Owner、Scrum Master)不超过10人,Team应该是一专多能的全才型选手,而不是那种专业化分工的团队,这样才能保证团队的效率比较高,也易于沟通。团队成员都应该是专职人员,不能同时兼职做多个项目。Team承担了如下的细分角色。
(1)设计人员
对系统进行简单设计,并进行设计的讨论。
(2)实现人员
负责实现整个系统,并对系统执行单元测试,构建整个系统。
(3)自我管理人员
大家一起来估算,一起来选择任务,一起来跟踪任务进展。
Product Owner定义了项目做什么,Scrum Master从过程上保证了如何实现项目,Team从技术上保证了如何实现项目。
2.1.2 Scrum的3个文档
在Scrum方法中明确要求了3个文档。
(1)产品待办事项列表
(2)迭代待办事项列表
(3)燃尽图
1.Product Backlog
Product Backlog 中列举了本项目应该实现的需求,需求采用了用户故事的方式进行描述。用户故事是一句简短地采用用户熟悉的术语表达的需求,是用户讲给开发人员的故事,不是开发人员讲给用户的故事。既然是故事,就要有人讲,谁讲呢,是Product Owner来讲。每次讲时可能都有细节的不同,就要有变化,但是万变不离其宗,所以故事本身是有一定弹性的。故事可以有标准的格式,笔者称之为三段论式故事。哪三段呢?
(1)用户角色
(2)需要的功能
(3)目的
比如,有这样一个故事:
作为一个家庭主妇,我需要一个30平米的餐厅,以便于我可以招待10位朋友来用餐。
用户角色是家庭主妇,30平米的餐厅是功能需求,招待10位朋友用餐是为什么需要这个功能。千万不要小看这个三段论式的故事,需要仔细琢磨每一段的作用。用户角色表明了是谁使用这个功能,如果一个功能没有明确的使用者,是否可以删除呢?如果一个用户角色不重要,是否这个需求的优先级比较低呢?目的说明了为什么需要这个功能,这个功能解决了什么问题,如果一个功能没有明确的目的,是否可以删除呢?如果目的不太关键,这个需求是否可以优先级比较低呢?
优先级?没错,我多次提到了优先级,需求一定要分优先级!谁来划分需求的优先级?Product Owner!如何划分优先级?根据商业价值!根据对客户、对最终用户的商业价值来划分优先级。如何区分商业价值的大小呢?比如提问如果不实现此需求,如果推迟实现此需求客户是否会不满意?是哪类人不满意?不满意到什么程度?一个称职的Product Owner可以凭经验划分出需求的优先级。
是否仅仅描述了这样一句话就充分了呢?其实还有第四段,即用户故事的验收标准,或者称为用户故事的测试要点,这也是由Product Owner完成的。Product Owner可以先完成前三段,在和Team Member的沟通过程中逐步丰富完善验收标准。对于前面我们提到的那个故事,如果你实现了这样一个餐厅,比如是一个2米宽、15米长的餐厅,那位家庭主妇会如何想?哈哈,如果她心理健康的话,估计她立马让你跳楼!如果她心理不健康,她会跳楼的。当然在敏捷方法中不会出现这种现象,在开发过程中,Product Owner会与你随时沟通交流需求,在沟通中Product Owner还传达了这样的信息:
(1)我希望这个餐厅是5米×6米;
(2)我希望这个餐厅灯光明亮;
(3)我希望这个餐厅靠近厨房,我不希望超过10步;
(4) ......
这就是验收标准!也可以换一种角度,从如何验收的角度来描述:
(1)我会量量这个房间是否是5米×6米。
(2)我会测测如果在这个房间里白天打扑克,不开灯的话,能否看到扑克的花色和点数;
(3)我会测测从厨房到餐厅需要走几步;
(4)......
如果一个故事提不出来验收标准怎么办呢?不实现它,晚实现它,直到明确了验收标准。
到目前为止我们实际讲了在Product Backlog中包含了5段:
Product Backlog = 需求 + 优先级
= 用户故事 + 验收标准 + 优先级
= 用户角色 + 功能 + 目的 + 验收标准+优先级
也有将验收标准单列出来的,但我认为验收标准应该是需求的一部分,只不过换了一种描述需求的方式而已,所以还是作为Product Backlog的一部分比较好吧。
前面我一直在提“功能”二字,没有提非功能的需求,如果有非功能的需求怎么办?两种处理办法,一是如果能明确到某个故事,就描述在故事的验收标准中;二是写一个“技术故事”,单列出来,提醒开发人员注意这些故事,这个故事未必是Product Owner提出的。
对于用户故事我们希望能够达到如下的理想:
(1)独立性。尽可能避免故事之间存在依赖关系,故事之间存在依赖关系会造成划分优先级的困难,在安排开发顺序时需要考虑故事之间的依赖关系。
(2)可协商性。故事是可协商的,故事是有弹性的,故事是需要讲的,不是必须实现的书面合同或者需求。
(3)对用户或者客户有价值。确保每个故事对客户或用户有价值的最好方式是让用户编写故事。
(4)可预测性。开发者应该能够预测(至少大致猜测)故事的规模,以及编码实现所需要的时间。
(5)短小精悍。一个故事在一个迭代周期内一定是可以实现的,而我们提倡短周期迭代。
(6)可测试性。所编写的故事必须是可测试的,能够定义出验收标准。
注意,这是理想!
Product Backlog在项目进展过程中是会发生变化,只有Product Owner有权来修改此文档。你可以用Excel文件来描述它,也可以采用一些敏捷项目管理的工具来帮助你维护,或者使用一些缺陷的跟踪工具如JIRA之类的。最直观、最朴素的办法是采用即时贴,直接贴在办公室的白板上,让大家都能随时看到。
2.Sprint Backlog
Sprint Backlog就是任务列表,如果映射到传统的项目管理理论中就是WBS(Work Breakdown Structure),而且是典型的采用面向交付物的任务分解方法得到的WBS。注意,在PMBOK中,WBS分解到工作包级,此处的WBS是指分解到具体的活动级。
比如有一个Product Backlog 条目为:
作为系统的合法用户,可以通过录入账号和密码登录到系统中。
为了实现此需求,Team Member识别出任务,进行了工作量的估计,进行了任务的认领,其结果记录表2-1所示。
表2-1 Sprint backlog案例(略)
此表格是由开发人员基于经验采用头脑风暴的方法大家一起分解得到的,里面列举的任务是为了实现该用户故事必须做的事情,按照简化的原则,可做可不做的任务则删除之。估计的工作量是由任务责任人自己估算的,任务的工作量合计应该不超过用户故事估算的工作量。如果任务拆分后发现工作量的合计远远大于用户故事估计的工作量,则可能需要对用户故事的工作量估算值进行修订。
Product Owner负责基于商业价值挑选某次交付中应该包含的用户故事,而开发人员负责基于开发的风险、用户故事之间的依赖关系等,挑选在某次迭代中要实现的用户故事。
Sprint Backlog可以采用Excel、白板或者敏捷的项目管理工具进行维护。
3.燃烬图
Burn Down Chart翻译为燃烬图(或燃烧图),很形象,是Scrum中展示项目进展的一个指示器。我一直认为用户故事、每日站立会议、燃烬图、Sprint Review、Sprint Retrospective真是越琢磨越有味道的好东西,也因此很喜欢Scrum这种方法,这些实践简单有效,非常经典。
燃烬图的样例如图2-4所示。

图2-4 燃烬图
横坐标为工作日期,纵坐标估计剩余的工作量,每个点代表了在那一天估计剩余的工作量,通过折线依次连接起所有的点形成估计剩余工作量的趋势线。另外还有一条控制线,为最初的估计工作量到结束日期的连线,一般用不同的颜色画上边的两根线。
对此图的研判规则如下。
(1)如果趋势线在控制线以下,说明进展顺利,提前完工的概率比较大;
(2)如果趋势线在控制线以上,说明延期的概率比较大,此时需要关注进度了。
注意,趋势线并非一直下行,也有可能上行,即发生了错误的估计或遗漏的任务时,估计剩余的工作量也有可能在某天上升了。
每天开完15分钟站立会议后,由Scrum Master根据进展更新燃烬图。第1个点是项目最初的工作量估计值,第2个点是最初的估计工作量减去第1天已完成任务的工作量,依次类推计算后续的点。任务完成的准则如下。
(1)开发人员检测:所有的单元测试用例都通过了。
(2)Product Owner检测:通过了所有的功能测试。
燃烬图最好是张贴在白板上,让每个项目成员抬头就能看见,这样给大家一个明确的视觉效果,每个人随时都能看到我们离目标有多远。
燃烬图可以每天画,表示完成某个迭代的进展趋势,也可以在某次迭代结束的时候画,表示完成整个项目的进展趋势,此时横坐标就是迭代的顺序号。
燃烬图和传统项目管理理论中的挣值图比较起来更加简单、直观,这种设计深得管理的精髓!度量的精髓!真是让人佩服!
在敏捷方法中提倡看板管理,将这3个文档都贴在一个白板上,让项目组的所有成员都能一目了然。
案例:项目管理看板
图2-5为2013年6月份笔者摄于北京某家客户处。

图2-5 看板
4种会议
在Scrum方法中定义了4种会议活动。
(1)Sprint Planning。
(2)Daily Meeting。
(3)Sprint Review。
(4)Sprint Retrospective。
除去开发活动外,这4种会议构成了Scrum方法的核心活动。这4种会议的要点如表2-2所示。
表2-2 4种会议的要点
案例:敏捷迭代总结
2012年杭州某公司的一个项目组采用敏捷的方法完成了一个项目,在此过程中,每次迭代结束后,项目组的每个成员都总结了本次迭代的经验教训,这些总结很有代表性。我汇总了这些经验教训,点评如下。
如何开每日站立会议
每日站立会议是Scrum方法中的一条关键实践,看似很简单的一个活动,其实内涵丰富,站立会议通过每天面对面的沟通,可以:
(1)快速同步进展,让项目组内部的员工互相了解彼此的进展,从而了解本项目的整体进展。
(2)给每个人一种精神压力,信守承诺。这是一种面对面的精神压力,直面项目进展。
(3)培养团队的文化,让每个人意识到:我不是一个人在战斗,我们是一个团队。
为了保证每日站立会议的质量,需要注意如下的要点。
1.任务的分配与领用
(1)任务的责任人要明确。
(2)任务的颗粒度小于2天。
(3)如果有的任务颗粒度实在无法拆分到2天以内,则需要设置中间的检查点。
(4)任务的完成时间要明确。
(5)任务的完成标准要明确。
(6)任务识别要尽可能完备,不要在过程中增加很多遗漏的任务。在识别任务时,团队中的各个角色都要参与,要充分讨论。
(7)增加、修改的任务要增加小贴纸,明确地在看板中标识出来,这些任务可以采用不同颜色的贴纸标识。
(8)高层经理不要越级直接给团队成员下达任务。
2.任务的完工检查
(1)不能只靠责任人汇报说完成了就认为任务已经完成了,应该有检查。如果是编码,则要通过规范符合性检查、工具静态检查、人工代码走查或单元测试,并通过Product Owner的确认。如果是编写文档,则应该通过了评审,如果是预研,则应该展示预研的结果。
(2)要区分任务的完成与需求的完成。需求的完成需要多个任务完成的支持,不但要跟踪任务的进展,也要跟踪需求的进展。如果不是采用迭代模型,而是采用瀑布模型,可以定义一个任务进展的内部准则。比如对于一个需求,如果需求定义完成,则认为这个需求完成了10%;如果详细设计完成,则认为这个需求完成了30%;如果代码完成,则认为这个需求完成了50%;如果单元测试通过,则认为这个需求完成了70%;如果系统测试完成,则这个需求认为完成了100%。
3.进展的跟踪
(1)采用燃烬图标识每个小组的进展,每天站立会议完成后更新燃烬图;
(2)采用燃烬图标识整个产品开发团队的进展,可以每天或每2天更新燃烬图。
(3)每个小组、整个产品的进展都要及时跟踪。不能关注了局部,忽略了整体。
4.站立会议
(1)每天定时、定地开站立会议,不需要事先通知。
(2)在站立会议上每个人当且仅当回答以下3个问题:
昨天完成了什么?
有什么难题需要别人帮助解决?
今天做什么?
(3)在汇报每个人的进展时,不需要汇报是如何做的,只汇报进展;
(4)需要别人帮助的问题在会后单独讨论。
5.小组长
(1)主持会议,确保每位组员发言时不能跑题。
(2)可以点评、提醒每个人的工作,但是一定要简短点评。
(3)如果对总体情况进行总结,一定要简短。
6.会议纪律
(1)不能迟到。如果迟到就惩罚之。
(2)只有一个声音在发言。不能一个人在发言,其他人在开小会。
(3)非本小组的成员,可以旁观,不需要发言。
(4)不能中途有人退席。有的人汇报完自己的进展后就退席是不允许的。
7.物理设施
(1)站立会议时一般要有白板,白板上粘贴的是本项目组的任务状态:未开始的任务,进行中的任务,中断的任务,完成的任务。其实也有一些敏捷的工具,可以电子化Sprint Backlog,但是还是不如物理的白板更有视觉的冲击力。
(2)白板的面积要大,如果所有的任务不能在白板上贴下,则可以只贴本次迭代的或最近一段时间的,比如2周的。
(3)如果白板面积不够,可以不用贴纸,手写任务。
(4)贴纸容易掉,可以用小磁条或不干胶粘在白板上。
(5)限于办公环境,每个小组的站立会议可以错开时间开。
8.其他注意事项
(1)一定要当面开会,不能邮件替代站立会议。
(2)一定要每天开会,每天跟踪项目的进展。
(3)不需要整理会议纪要,除非有其他必须的目的。
案例:站立会议
2010年深圳某客户在公司内推广站立会议,2010年4月份笔者曾经到这家客户观察过1个大产品的10多个项目小组执行站立会议的情况,并将结果与体会记录整理成了一篇博文:《每日站立会议的10个成功要点》。2013年8月23日上午(深圳,滂沱大雨,雨声如鼓)故地重游,我又观察了该公司一个项目的站立会议,记录如下。
(1)某项目组站立会议,早上9点13分开始,9点26分结束,费时13分钟。
(2)人员陆续而来,9点13分开始后,9点15分、9点20分、9点21分分别又来了3个成员,累计13个人参与了该会议。
(3)主持人是打开一个Excel格式的计划,对此计划进行跟踪,计划中包含的列有:任务、任务描述、任务跟踪记录、计划开始日期、计划结束日期、任务状态、责任人。
(4)主持人采用轮询的方式跟踪任务进展,边询问,边记录到Excel计划的任务跟踪记录列。
(5)主持人了解每个人的进展后,进行了简单点评,有问题则给出了指导意见,项目组其他成员也给出了一些建议,所有的问题当场都给了结论,需要尝试的,让项目组成员去尝试了。
(6)项目组成员彼此之间有接口的,互相询问、沟通了接口的进展情况。
(7)在某个成员汇报工作进展的时候,有的成员没有专心听,而是和其他成员开小会,在讨论自己感兴趣的话题,主持人没有制止。
(8)有的项目成员在整个过程中游离在团队之外,不关心别人的进展,始终在玩自己的手机。
(9)在跟踪任务进展过程中,经过简短讨论后,主持人随时增加了一些必须的任务,并责任到人了。
(10)没有画燃烬图。
(11)未按时完工的任务大都是需要其他项目组配合完成的任务。
总评:一项简单的措施坚持下来不容易,坚持做好更不容易。
XP极限编程的12条实践
极限编程(Extreme Programming,简称XP)是一种敏捷的软件开发方法。在迭代生命周期模型中贯穿了12条实践。
(1)现场客户:此实践继承自快速应用开发(RAD)方法的用户驱动的开发,要求客户、用户或其代表全程参与开发的过程,和开发人员一起工作,其职责为:
需求定义、需求讲解、需求优先级制定、需求验收标准定义、功能测试、功能验收。
此实践中的客户和Scrum方法中的Product Owner的职责类似。
(2)策划游戏:在XP中项目计划划分为2个层次:发布计划与迭代计划。在定义计划时,要进行以下4次的平衡。
① 项目的估算总工作量(需求工作量)与项目组成员可以提供的工作量(开发能力)的平衡。
②某次发布的需求工作量与在本次发布内项目组成员开发能力的平衡。
③某次迭代的需求工作量与本次迭代的项目组成员开发能力的平衡。
④ 某次迭代内某个人的任务工作量与其开发能力的平衡。
估算工作量时可以采用策划扑克法或其他敏捷的估算方法。
(3)小版本发布:频繁发布软件版本供用户、客户进行确认,以尽早取得客户的反馈。
(4)平稳的开发速度:两层含义,一是每周工作40小时,不加班,让开发人员高效地、愉快地工作。二是避免快而脏的开发模式,在开发过程中保证质量的投入,不要到项目的后期集中改错。
案例:平稳的开发速度
我的一位同事采用敏捷方法做软件开发很多年,他曾经有过这样一个经历:有一次项目组新加入了一个员工。这位新员工以前没有敏捷开发的经验,他对项目组其他成员坚持做单元测试、持续集成很不以为然,认为大家的开发速度比他慢很多。在迭代结束联调时,其他人的代码很快就能集成并测试通过,而他的代码却问题很多,别人都下班回家了,唯独他需要留下来加班修改错误,经过2次迭代后,此人终于意识到了敏捷实践的优点。
(5)系统隐喻:对于系统的架构设计、概要设计,采用类比或比喻的方式进行设计,便于项目成员之间互相快速、通俗地沟通系统的设计思想。系统隐喻对于设计人员的水平要求比较高,因为将系统抽象的设计思想采用通俗的类比刻画出来需要较高的设计水平。
(6)简单设计:不为未来不确定的变化进行设计,不进行过度设计。
(7)结对编程:两人共用一台计算机工作,两人一起协商进行编程,结对不是固定的,每天调整结对的人员。很多软件公司对此实践则进行了变通执行,如:
① 每天早晨进行半小时的结对设计,每天下午下班之前进行一小时的结对代码走查。
② 执行结对修改。当修改错误或需求变更时才进行结对,其他时间不结对。
(8)编码规范:定义项目组的编码标准和规范,要求成员一致地执行,可以采用工具进行编码规范的静态检查。
(9)测试驱动的开发:在完成需求后即进行验收标准的编写,在写产品代码之前优先进行单元测试代码的编写,在编码过程中可以随时进行单元测试。
(10)持续集成:代码通过单元测试后可以与其他已经完成的代码进行编译链接,然后执行静态检查、单元测试等。此工作是实时进行或者定期进行,可以在持续集成的服务器中设置集成的策略。
(11)重构:重构是在不改变代码的外部行为的前提下,优化内部的实现方法。当修改错误时,当需求变更时,当代码评审时,可以对代码的坏味道进行重构。
(12)代码集体所有:项目组的所有成员对所有的代码共同负责,当发现代码的改进点时谁都有权利、有义务进行代码的优化。
这12条实践是相辅相成的,必须一起采纳才可以称得上是极限编程方法,不能仅仅采取了其中几条措施就称为极限编程了。在这12条实践中,后6条实践是紧紧围绕编码活动的,系统隐喻与简单设计是针对设计活动而言,在客户现场实践中包括了需求开发与功能测试、验收测试的活动。因此,我们说XP是侧重于工程活动的一种敏捷开发方法,75%的实践都是工程活动。
在实践中通常是将XP方法与Scrum方法配合在一起使用,一种方法覆盖了工程活动,一种方法覆盖了管理活动,二者互补。
时间箱管理
时间箱管理是敏捷方法中的一条实践,其含义是项目中某些活动的完成时间必须在规定的时间内完成。该实践有助于提高整个项目的工作效率,避免帕金森现象。
在敏捷方法里,时间箱管理的具体体现以下几点。
(1) 每次迭代必须在固定的时间内完成,比如2周或1个月。每次迭代必须交付一个质量得到充分检验的、可以运行的软件版本。如果有些需求不能在某次迭代内完成,则推迟到下一个迭代中完成。
(2) 项目的策划会议必须在4个小时内完成,某次迭代的策划会议必须在4个小时内完成。
(3) 每天15分钟的站立会议。
(4) 在每日站立会议上发现的问题要在1天内解决。
(5) 1个小时内做出决策。需要项目的负责人或教练对于管理的问题在1小时内做出决策,不能拖延决策。
(6) 每次迭代结束后的评审会议必须在2个小时内结束。在迭代评审会议上主要是示范本次迭代完成的产品或产品构件,获得客户及相关人员的反馈。
(7) 每次迭代结束后的总结会议必须在2个小时内结束,通常是在30分钟内结束。主要是总结本次迭代的经验教训,下次迭代能够做得更好。
上述规则中的具体时间数字并非是绝对的,每个项目组可以根据自己的实际情况自行定义。
策划扑克法
策划扑克法是估算软件规模与工作量的一种敏捷方法。该方法的规模计量单位是故事点(Story Points),故事点只是一个计量单位的名称而已,你也可以给它命名为其他名字。故事点其实不仅仅是对规模的度量,也包括了对需求复杂度等其他因素的度量。故事点并非业界统一的一个度量单位,不像度量长度的单位:米。大家都知道1米有多长,你说的1米和他说的1米是等长的。故事点仅对本项目具有近似相等的规模,不同的项目所定义的故事点很可能是不等的。
策划扑克法参与的人员包括了所有开发人员:程序员、测试人员、数据库工程师、分析师、用户交互设计人员等等,在敏捷项目中一般不超过10人。产品负责人参与策划扑克法但是并不作为估算专家,如图2-6所示。

图2-6 策划扑克法
策划扑克法的步骤如下。
(1)每位参与估算的开发人员发放一副估算扑克,扑克上的数字标为近似的斐波那契序列:1,2,3,5,8,13,20,40。
(2)选择一个比较小的用户故事,确定其故事点,将该故事作为基准故事,作为参照物。
(3)从其他故事中任意选择一个用户故事。
(4)主持人朗读描述。主持人通常是产品负责人或分析师,当然也可以是其他任何人,产品负责人回答估算者提出的任何问题,大家讨论用户故事。
(5)每个估算者对该用户故事与基准故事进行比较,选择一个代表其估算故事点的牌,在主持人号令出牌前每个人的牌面不能被其他人看到,然后大家同时出牌,每个人都可以看到其他人打出的牌。
(6)主持人判断估算结果是否比较接近。如果接近则接受估算结果,转向步骤(3)选择下一个故事,直至所有的用户故事都估算完毕,否则转向步骤(7)。估算结果是否比较接近的规则,项目组可以自行定义。
(7)如果结果差异比较大,请估算值最大及最小的估算者进行解释,大家讨论,时间限定为不超过2分钟。如果大家同意,也可以对该用户故事进行更细的拆分。
(8)转向步骤(5),一般很少有超过3轮才收敛的现象。
在该方法中,参与的人员对于被估算的需求进行了充分的沟通,并综合了程序员、测试人员等各个角色的专家观点,融专家法、类比法、分解法为一体,可以快速、可信、有趣地进行估算。
在估算完故事点后,可以凭经验估算一个故事点的开发工作量,从而得到所有的用户故事的工作量。也可以进行试验,试着开发一个用户故事,度量花费的工作量,得到开发效率,即在本项目中一个故事点需要花费多少工时,再去估算所有故事的工作量。
敏捷度量
在敏捷方法中,要求度量的数据少之又少,可谓简单实用。
(1)规模
故事点:用以估算工作量、度量开发效率。
(2)工作量
计划的工作量:用以排定项目计划。
剩余任务的计划工作量:用以跟踪项目进展。
(3)效率
开发速度:每次迭代完成的需求的规模(如故事点),用以估算项目需要的迭代次数。
其他度量元根据项目组的实际情况,可以由项目组自己定义。
关于敏捷方法的典型问题
2012年12月8日晚,笔者和两位朋友聊天,他们从国外的大企业工作了多年,回国创业开办了一家软件公司,按照敏捷的方法进行了2年的软件开发。在实践中有些具体的问题,大家在一起进行了沟通讨论,从敏捷方法的文化到敏捷方法的具体实践的做法,沟通了大概3.5小时,第1个小时的沟通笔者忘记录音,后边的沟通笔者做了录音。根据回忆和录音,将讨论的问题整理如下,属于“非典型企业的典型问题”。
什么是敏捷方法的“神”
在实施敏捷方法时,遇到了“形似而神不似”的问题,敏捷方法的“神”究竟是什么?
我总结为两条:质量与沟通。很多企业是没有把握住这2条,而导致敏捷的失败。先说质量。
(1)在敏捷方法中,“多快好省”四个字进行平衡时,首先是要固定质量,在固定质量投入的前提下,再去平衡进度、需求和投入。在剩下的这三个要素中,往往先裁剪需求。
(2)质量的含义包含了内部质量和外部质量。外部质量是用户可以感知的,是对需求的符合性。内部质量是开发人员感知的,决定了软件的易维护性。内部质量决定了外部质量,敏捷方法是二者并重的,并非仅仅关注了外部质量,但传统的方法往往仅关注外部质量。
(3)质量的管理首先关注质量的投入。质量的投入表现在质量管理的活动上:测试驱动的开发、静态检查工具的使用、结对编程、代码走查等。没有质量的投入就没有质量的产出。敏捷方法对于质量应该如何投入给出了具体的实践,而不仅是停留在概念上。
(4)提升软件开发效率的最有效方法是减少返工,一次做对是提升效率的最有效方法,因此就要预防错误。预防错误的方法包括和开发人员对需求的理解达成一致,结对设计,测试驱动的开发,结对编程等。
再说沟通。
(1)敏捷方法为什么可以少写文档,因为它通过口头交流的方式替代了文档交流。有哪些具体的口头交流的手段呢?在策划会议上项目成员对用户故事做了沟通和讨论,开发人员做了结对编程,每天开了站立会议,用户代表或产品负责人在过程中实时地做功能测试等等,这些手段都保证了在文档比较少的前提下,可以保证产品的方向、产品的具体功能不会偏离用户需求。
(2)在敏捷方法中沟通了什么?首先是需求,其次是设计,再次是进展,最后是经验教训。在需求方面沟通了对需求的理解,需求是否实现了,需求的沟通是重中之重。用户故事是用来讲的,是用户讲给开发人员听的,开发人员是否实现了听来的故事,是需要讲故事的人进行确认与验收的。对于需求、对于进展都要尽早地报告坏消息:如需求理解错了;需求无法实现;需求实现错了;需求没有按时实现。
在敏捷宣言中讲到了4条宣言,在XP方法中有4个价值观,在这些描述中笔者体会最关键的还是这2条。
每个开发人员要将以上的2条落实到他们每个人的细节行动上,大家需要不断反思:做这件事情你是否保证了质量?是否通过沟通减少了错误的发生?
如何建立团队文化
团队文化就是互补的文化,就是互相配合、互相帮助的文化。在中国的教育体系中,从小学到大学都没有培养团队协同的思想与理念。每个人的单兵作战能力还可以,但是大家不知道如何形成一个团队,从项目经理到团队的成员都缺少这方面的思想认识或具体的做法。团队文化包括了积极主动的文化、互相协调的文化。比如在开站立会议时,就有人只是关注自己的工作,不关注团队中其他人的工作,你的是你的,我的是我的,而不是我们的。也有的人认为我的就是我们的,是我们的那就不是我的,不是我的所以我也就没有责任。
如何形成团队文化?
(1)在一个公司中,企业的文化首先是老板的文化,老板的一言一行影响了员工。我们可以比较一下联想、华为、富士康等企业的文化,你就可以发现这个结论。如果一个团队没有形成一个良好的文化,首先领导就要反思,是否自己的言行出了问题。
(2)小团队容易形成团队文化,而大团队形成团队文化就比较困难。小团队靠人治,大团队靠法治。敏捷方法中提倡小团队,其中一个好处,就是容易形成这种互相配合、互相协同的文化。
(3)文化体现在细节,文化需要不断地进行重复强化。要从每个细节活动中去反思是否符合团队的文化。
(4)文化的载体有2个:规章制度与人。通过企业的规章制度体现企业的文化,通过以老带新来传承文化。
如何运用敏捷实践解决其他问题
有些比较复杂的任务、不够清晰的任务,比如编写文档等是否适合采用敏捷方法来管理?在XP中有结对编程,适用到对客户的支持时可以借鉴结对的思想。如何保证质量?如何通过沟通减少中间记录?对于文档的编写我们可能不使用结对编写文档,但是我们是否可以对这个文档进行评审呢?在写文档之前我们是否对文档做了结构的设计呢,就像我们做系统隐喻一样呢?是否做了方案的讨论,我们都可以借鉴敏捷的实践,你也可以把它作为一个用户故事,一个用户故事就是一个需求而已。
只要明白了敏捷的思想,你只要类比就可以了。比如用户故事的四段论,看上去很简单,谁要这个功能?什么功能?为什么要这个功能?有了这个功能如何验收?不能假想功能,做了功能没有人使用,这个功能要解决什么问题?目的是否明确?通过验收的标准进一步澄清目的。我们把这个思想类比到日常工作中,我们给一位员工下达一个任务时,常常发生对方没有按我们的要求完成任务,需要进行返工,尤其是布置任务的人比较繁忙时,往往是简单说了一句,布置一下任务就放手让别人去做事情了。如果我们借鉴用户故事的方法,我们可以这样给其他人安排任务,我想让你做什么事情,为什么要做这件事,你做完了以后,我会检查哪几点,这样就可以减少很多误解和返工。看上去用户故事是很简单的一条实践,但是你需要仔细琢磨这条实践解决了什么问题,它背后的道理是什么。
如何理解平稳的开发速度
欲速则不达。平稳的开发速度如何理解?如何提升软件开发的效率?不返工就能提高速度吗?如何不返工?在做之前做了充分的设计,传统方法是写文档和评审,敏捷方法是讨论,是三个臭皮匠顶一个诸葛亮。
每次迭代结束后,大家做回顾,提升团队的能力。每次迭代结束后团队的整体能力应该有长进,开发的速度越来越快,越来越稳定,是个正反馈的自适应过程。
要通过成功走向成功来激励员工,每次迭代要能成功结束,而不是每次迭代都要会失败。每次迭代结束后要调整下一次迭代的开发速度,确保下一次迭代是切实可行的。
敏捷始于客户
每个失败的项目都可以找这个借口:项目周期短、需求变化快、人员有限。
需求、工期是由客户确定的。作为客户来讲,他不可能去合理地评价给定的需求是否可以在某个时间内完成,至于投入多少人则更是开发方自己的问题。
开发方对客户做出了承诺就要兑现承诺,否则就不要承诺,既然承诺了,就没有理由再去抱怨工期短、需求变化快。开发方必须接受这个现实,认可这个现实。
CMMI是应对这种局面的一种解决方案,CMMI是全球最大的软件客户—美国国防部资助开发的模型,是甲方驱动的模型,是得到甲方认可的方法。敏捷方法呢?敏捷方法如果能够真正推行开来,同样也需要客户的认可。
敏捷方法的推广应该始于客户,始于甲方:
(1)需要甲方认可质量第一,功能多少与工期第二。
(2)需要甲方对需求划分优先级。
(3)需要甲方认可分批地、阶段性地交付系统。
(4)需要甲方参与阶段性确认或者全权委托代表进行阶段性确认。
(5)需要甲方在开发过程中安排熟悉需求、有需求决策权的专家参与项目,与项目组保持实时沟通。
否则,不具备成功的基础,则敏捷的开发管理仍然会失败。
软件工程7原则与敏捷实践
Barry Boehm于1983年提出了软件工程的七原则(Seven Basic Principles of Software Engineering),这是很经典的七个原则,有人将题目翻译为软件工程的七个基本原理,其实,principles在此处还是翻译为原则更为准确。依据原文笔者对于各原则的理解如下。
原则一:使用分阶段的生命周期计划管理(Manage Using a Phased Life-cycle Plan)
(1)一定要有项目计划。
(2)项目要划分生命周期阶段,每个阶段都要有计划。
(3)计划要分层或分阶段逐步细化。
(4)要使用项目计划管理项目,不能弃之不用。
原则二:执行持续确认(Perform Continuous Validation)
(1)尽早发现错误。大部分缺陷是编码之前注入的,缺陷越早修复,成本越低。
(2)尽早发现错误的措施,包括:深入评审;设计阶段编写用户手册、使用手册、数据准备手册;原型;模拟;自动化的检测工具;设计审查与走查;等等。
原则三:维护规范的产品控制(Maintain Disciplined Product Control)
执行配置管理,确保工作产品之间的一致性。
原则四:使用现代化的编程实践(Use Modern Programming Practices)
采用现代化的开发方法、开发实践提升软件的效率与质量。
原则五:维护关于结果的清晰责任(Maintain Clear Accountability for Results)
对于项目的阶段产出、各个小组之间的承诺、每个人的产出与承诺要明确,要可验证。
原则六:使用少而精的人员(Use Better and Fewer People)
(1)人与人之间的效率差别达10倍甚至25倍以上,因此要使用精英团队。
(2)采用多种方式提升沟通的质量与效率,包括:不要通过加人的方式解决进度问题;项目的初期不要太多的人员;为高性能提供高的回报;淘汰低性能者;使用自动化的辅助工具。
原则七:坚持过程改进的承诺(Maintain a Commitment to Improve the Process)
识别、分析技术与过程的改进,建立持续改进的机制。
如果仔细去分析敏捷的软件开发方法,则可以发现,恰恰敏捷的实践很好地满足了上述七个原则。
表2-3 软件工程七原则与敏捷实践