摘至 邹欣《构建之法》一书,以作学习之用
在软件工程的语境里,“敏捷流程”是一系列价值观和方法论的集合
现有的做法 | 敏捷的做法 |
---|---|
流程和工具 | 个人和交流 |
完备的文档 | 可用的软件 |
为合同谈判 | 与客户合作 |
执行原定计划 | 响应变化 |
尽早并持续地交付有价值的软件以满足顾客需求
敏捷流程欢迎需求的变化,并利用这种变化来提高用户的竞争优势
经常发布可用的软件,发布间隔可以从几周到几个月,能短则短
业务人员和开发人员在项目开发过程中应该每天共同工作
以有进取心的人为项目核心,充分支持信任他们
无论团队内外,面对面的交流始终是最有效的沟通方式
可用的软件是衡量项目进展的主要指标
敏捷流程应能保持可持续的发展。领导、团队和用户应该能按照目前的步调持续合作下去
只有不断关注技术和设计,才能越来越敏捷
保持简明—尽可能简化工作量的技艺—极为重要
只有能自我管理的团队才能创造优秀的架构、需求和设计
时时总结如何提高团队效率,并付诸行动
1. Scrum 这个方法论
从理论上看,这个方法论真是美妙无比,微软MSDN也有类似的流程介绍,看起来也是高屋建瓴,很流畅:
敏捷的步骤:
第一步:找出完成产品需要做的事情—Product Back-log
Backlog翻译成“积压的工作”、“待解决的问题”、“产品订单”,都可以。产品负责人主导大家对于这个Backlog进行增/删/改的工作。每一项工作的时间估计单位为“天”
第二步:决定当前的冲刺(Sprint)需要解决的事情—Sprint Backlog
整个产品的实现被划分为几个互相联系的冲刺(Sprint)。产品订单上的任务被进一步细化了,被分解为以小时为单位。如果一个任务的估计时间太长(如超过16个小时),那么它就应该被进一步分解。订单上的任务是团队成员根据自己的情况来认领。团队成员能主导任务的估计和分配,他们的能动性得到较大的发挥
第三步:冲刺(Sprint)
在冲刺阶段,外部人士不能直接打扰团队成员。一切交流只能通过Scrum大师(Scrum Master)来完成。这一措施较好地平衡了“交流”和“集中注意力”的矛盾。有任何需求的改变都留待冲刺结束后再讨论
冲刺期间,每天要开一个每日例会(Scrum Meet-ing),团队成员大多站着开会,所以又称每日立会。大家依次报告:
每日立会强迫每个人向同伴报告进度,迫使大家把问题摆在明面上。同时启动每日构建,让大家每天都能看到一个逐渐完善的版本。用简明的图表展现整个项目的进度,这个图最好放在大家工作的环境中,或者每天传达给各个成员:图表可以是燃尽图(Burn Down Chart,想象我们把一堆Backlog的木头给烧光)。
冲刺阶段是时间驱动的(Time-boxed),时间一到就结束。这个特点看似不起眼,但其实它有效地断了各种延期想法的后路,很高明
第四步:得到软件的一个增量版本,发布给用户,然后在此基础上又进一步计划增量的新功能和改进
美妙的理论在实践中都会碰到这样那样的问题,下面是一些例子。
第一步:
各个需求和任务之间是有种种复杂的依赖关系的,除了优先级之外,我们还要考虑相互的依赖关系。怎样在计划(Backlog)中体现依赖关系呢?
第二步:
把一个任务从产品层级的描述逐步细化到技术实现层面,是很需要技术能力和交流能力的。例如,产品订单上写着:
希望这个英语单词学习软件能在各个移动平台上实现用户学习进度的同步
那么,在把这个任务分解到一个可以执行的冲刺任务时,我们要考虑这些因素:
什么是用户学习进度?用户如何衡量这个功能的优劣?
PC平台和各个移动平台分别用什么来表示“学习进度”?
同步是通过什么样的技术手段实现?
如何解决可能的同步冲突问题?
第三步:每日例会(Scrum Meeting)看起来很爽:
爽了之后,也许会流于形式。我们想象一帮狗熊开每日例会时,大家的发言是:
每天这样写代码,我们离冲刺的终点线到底是更近了,还是更远了?如果流于形式,无论多么敏捷的每日立会也会被忽悠
一个改进是,定义好任务究竟是什么?任务的完成(Done)到底意味着什么?每个人的任务必须是明确定义的,狗熊们不能笼统地说“我在掰棒子”,而是要说明标号为123的棒子现在是什么状态,你做好之后交给谁了
另一个改进是,要在每一个任务中记载我们完成这个任务还需要多少时间。已经花了多少时间虽然重要,但那不是关键(那是沉没成本),关键是要看我们离最后目标有多远。就像某部门展览“反腐成果”给群众看—“已经抓出来N个腐败分子”固然解恨,但关键是“还剩多少在台上”,这个问题不说明,再抓多少个都不解决问题
冲刺到一半的时候,产品负责人突然发现要马上做重要的改动!或者某个大佬要看某个不在计划中的功能的演示,怎么办?这种情况非常考验ScrumMaster
一个有正常头脑的运动员和教练员会说:去你的,要改主意,也要等到老子冲刺完了再说啊!
在实践中,以时间为度量的燃尽图更有效果。下面是一个实际项目的燃尽图,有三个每天跟踪的时间值:
实际剩余时间(Remaining Hour):每个团队成员所有任务的剩余时间的总和
预估剩余时间(Projected Remaining Hour):根据每个人每天的理论进度推算的剩余时间
实际花费时间(Completed Hour):实际花费的时间
上图显示的是 Sprint 进行中
上图显示的是 Sprint 最后结果
(敏捷流程中的)第三步半:
做过项目的人都知道,当你说“任务都完成了”的时候,那只是说,开发人员认为该写的代码都写完了,但其实还有很多事情没做完。例如写一个Windows客户端的功能,显示一张新闻图片,加上与它相匹配的文字(假设这些图片/文字都可以从互联网上拿到),做完之后,还有下面的事情。
验证这个功能在Windows XP、Windows Vista、Windows7、Windows Server2008 R2、Win-dows Server2012下都显示正确。(开发人员表示自己的机器是Windows Server2008,UI看起来不错,其他平台想必也不错!)
验证这个功能的显示布局和字体在100%到150%的DPI上都显示正确,在各种色彩配置中都显示正确。
验证文字无论是中文、英文、阿拉伯文都能正确显示。(联合国五种工作语言我们得支持吧?)
验证程序效能上没有问题。
验证程序长时间运行,没有内存和资源泄露。
验证这个功能和其他功能有较好的集成
谁来做这第三步半呢?程序员写完功能的时候,我们感觉好像项目完成了80%,殊不知后面的20%往往要花费80%的时间,敏捷流程没有明确表明到底何人何时以何种优先级来完成这20%的任务
长期任务:软件项目中常常有一些比较艰难和底层的任务
完成这些任务需要超过Sprint所计划的时间,这些任务往往在短周期的迭代中得不到应有的重视,一直拖着,最后导致团队要花大量的时间来解决问题
软件团队中还有一个重要的角色—测试。测试人员在一个冲刺中怎么工作呢?有敏捷专家建议测试人员可以担负起产品负责人(Product Owner)的部分责任,同时掌握验收测试(Acceptance Test)流程,对产品的最终质量负责。但是测试人员的开发技术能力在团队中并不占优(在有些中国公司中甚至是最弱的一环),他们在大家都要“烧光”所有任务的压力下,能担当起产品负责人这一责任么?
“稳定和发布阶段”讲到了“第三步半要做什么事情”,它的流程图可以作为Scrum/Sprint的补充:
第四步:
得到了一个增量的软件发布,但是谁来验证这个增量是否满足了事先的计划呢?如果程序员们
在冲刺的过程中发现了新问题,改进了原来的计划,这是好事还是坏事?每一次冲刺结束后,大家要放松一下,总结上一次的经验教训,争取下一次做得更好。这个博客记录了微软学术搜索项目组10次冲刺的过程
软件开发流程有好多种,我们怎么衡量一个开发流程是否对当前的项目/团队合适?Scrum/Sprint能成功实施的关键在于Scrum Master。我听到有些团队也实施Scrum,但是他们随机挑一个成员来做Scrum Master,好像Scrum Master就是招呼大家开开会,记录每个人的进度而已。这种方法失败的可能性很大。一个好的Scrum Master能在两种语境(描述软件需求的商业语境,描述实现细节的技术语境)间自如地翻译和切换,事实上是一个强有力的项目经理(PM,参见本书“项目经理”一章)。如果团队还要求他/她做全职的开发工作,这样的人就更难找了。敏捷对团队的要求很简单:自主管理(Self-manag-ing)、自我组织(Self-organizing)、多功能型(Cross-functional),但是这很难做到。软件项目的团队各式各样(请看“团队和流程”一章),假设一个团队做得还不错,现在要变成敏捷流程,那团队要做下面的改变:
1. 自主管理:
以前领导布置了任务,我们实现就可以了,现在要自己挑选任务;每次Sprint结束之后,还要总结不足,提出改进,并且自己要实施这些改进。“自主管理”不等于“没有管理”。
2. 自我组织:
以前做好自己的事情就好了,安心下班。现在每个人要联合起来对项目负责,有人工作落后了还要帮助他改进,项目缺少某类资源还要自己顶上去。
3. 多功能型:
以前规格说明书由PM来写,测试由测试人员来做,现在每个人都全面负责,自己搞定规格说明书,和别人沟通,同时自己搞定测试。
如果你的团队很弱,那么强行把敏捷(或者其他高级方法)套在上面也没有用,也许还会适得其反,往往需要多次Sprint才能让Scrum走上正轨。换句话说,如果你的团队已经有这么厉害(自主管理、自我组织、多功能型)的一帮人,那么用不用Scrum都能写好软件!
敏捷总结与质量控制理论的模型如经典的戴明环(Plan-Do-Check-Act/Adjust,PDCA)没什么太大区别。正如肯·施瓦伯在描述Scrum的核心特点的时候所说:
在迭代开始时,团队审视摆在他们面前的任务,选择他们认为可以在迭代期间完成的那些任务(Plan)。然后团队独立地尽最大努力完成这些任务(Do)。在迭代结束时,团队给利益关系人展示成果(Check),并对开发流程进行调整(Act/Adjust)。
在六西格玛理论(Six Sigma)中,我们也可以看到相似的流程,只不过它变成了界定、量测、分析、改进、控制(DMAIC)。此模型不强调迭代的重要性。Scrum和渐进交付的流程(Evolutionary Deliv-ery)也很相似。
Sprint/Scrum对项目的众多需求采取分而治之的办法,能让相关人员集中精力,在一定期限内解决部分问题。它强调短时间的迭代(Iteration、Time-box),在多次迭代中不断总结,改进团队的流程和产品功能。它明确地指出不同的人在一个项目中的投入和责任的不同(参见“猪、鸡和鹦鹉的故事”这一节),并坚持让全身心投入的“猪”来主导项目。它通过Daily Scrum、Scrum Master等方法和角色,鼓励团队内部交流,并优化团队和其他人员的交流方式。它对团队成员提出了很高的要求:自主管理、自我组织、多功能型。一般人不能马上做到这一点。它不是“银弹”,不能解决软件开发的所有问题。至于具体项目进度如何跟踪,如何管理测试工作,如何管理复杂项目,还要靠战斗在一线的团队成员见招拆招,想出合适的办法。敏捷的众多方法看似容易,其实门道挺多
这里有一些实践者的经验教训:
敏捷宣言表明的是一些优先级,不必当作圣旨或者教条来争论。
Scrum Master不是一个官,而是一个没有行政权力的沟通者,就像微软的PM那样。他/她同时还要在团队中做具体的工作。直接把原来的“经理”变成Scrum Master,大多行不通。
一些项目需要很多暗箱操作和政治角力才能搞定,Scrum会把这些矛盾都摆到明处。这有好处,也有风险。
在复杂的项目里,要让一线团队成员做决定。
创业公司的团队其实经常是运行在Scrum 的模式中(只不过大家太忙,没工夫论证自己到底有多么Scrum)。
在Scrum计划阶段的估计不是一个“合同”,领导们不要把它当成一个合同。估计总是不准的。坚持短期的Sprint,这样即使不准的估计也不会有大的损害。
不要和管理层谈“流程”,他们只关心“结果”。
在大型团队、跨地区的团队,或者复杂项目中,Scrum并没有非常完美的答案,Scrum的创始人也承认这一点
1. 爱脚儿(Agile)——敏捷到底是什么东东?好像有很多名词、缩写和传说……
敏捷(Agile)是一股思潮,或者说是一种价值观,它涵盖了好几种软件开发的方法论(Methodol-ogy);这些方法论又是建立在许多行之有效的最佳实践方法(Best Practices)之上的。如下图所示
2. 敏捷的适用范围
客观因素\最适用方式 | 敏捷(Agile) | 计划驱动(Plan-driven) | 形式化的开发方法(Formal Method) |
---|---|---|---|
产品可靠性要求 | 不高,容忍经常出错 | 必须有较高可靠性 | 有极高的可靠性和质量要求 |
需要变化 | 经常变化 | 不经常变化 | 固定的需求没需求可以建模 |
团队人员数量 | 不多 | 较多 | 不多 |
人员经验 | 有资深程序员带队 | 以中层技术人员为主 | 资深专家 |
公司文化 | 鼓励变化,行业充满变数 | 崇尚秩序,按时交付 | 精益求精 |
实际例子 | 写一个微博网站 | 开发下一版本的办公软件;给商业用户开发软件 | 开发底层正则表达式解析模块;科学计算;复杂系统的核心组件 |
用错方式的后果 | 用敏捷的方法开发登月火箭控制程序,前N批宇航员都挂了 | 用敏捷方法,商业用户未必受得了两周一次更新的频率 | 敏捷方法的大部分招数都和这类用户无关,用户关心的是:把可靠性提高到99.999% ,不要让微笑的错误把系统搞崩溃 |
需要敏捷(Agile)的开发流程,但是不需要匆忙(Rushed)或忙乱(Chaotic)的开发流程。在实际情况下,有许多号称敏捷的项目好像也敏捷不到哪里去。要记住,有许多最佳实践在各种开发方式下都在使用,所以各种开发方式并不是井水不犯河水、老死不相往来的那种关系
3. 我想敏捷,但是项目的期限不能往后拖,敏捷能帮我早日完成任务么?
敏捷不是万能的。敏捷的方法能帮助你更早地知道你是否能如期完成任务,仅此而已。敏捷的方法(迭代的方式)能帮你尽快让用户看到项目的部分价值。当你尽早交付部分价值时,也许用户对你目前交付的东西已经很满意了,这样你就不用再花时间来实现其他需求。另一种可能是,用户看到了部分系统,他们有新的需求,这样你就可以实现新的需求,而不用再浪费时间实现过时的需求了。