本文是《敏捷热点问题的多角度杂议》(首次刊发在程序员杂志2011年9月刊)的一部分,为方便讨论,在这里独立成文。
敏捷软件开发宣言的第一个价值观指出“个体和互动 高于流程和工具”。“流程”对应的英文是“Process”,在有些地方也译为“过程”,下文中“流程”和“过程”为同义词。由于敏捷宣言和原则总共篇幅不长,并没有完全说明其中问题,导致了如下有趣又矛盾的现象:
1,部分敏捷的执行者抱怨以Scrum为代表的敏捷流程比较生硬,让员工都是那一副副苦逼的脸,一些团队依然察觉到许多刻板、教条之处,比如站会,Sprint的干扰,一旦听到ScrumMaster或团队试图“照着书本做Scrum”,就会为自己敲响警钟。
2,部分刚刚了解敏捷的人,尤其是团队以上的管理者,认为“敏捷不怎么讲过程规范,引入敏捷意味着冒较大的风险,为稳妥计,暂时先不搞敏捷了吧”。
敏捷软件开发宣言是在软件工程基础上提出来的,出发点所比对的是以瀑布型生命周期为核心的传统软件工程。Martin Flower把传统软件工程方法称为重型方法,敏捷为轻型方法。可以合理的推断敏捷宣言的意思是在传统软件工程已经得到了过程和工具的情况下,个体和互动更重要,并不是没有过程和工具,这点在Martin Flower的《新方法学》一文中也得到了表述。如果不站在软件工程基础上来采纳敏捷,那么很容易沦为软件作坊,其实这是违背敏捷的。
敏捷中给予软件开发团队最直接、最易操作的指导恰恰是在流程上,比如XP中的持续集成、TDD、重构等共12个实践,Scrum中的4种会议,FDD的5个流程等等。分析这些流程,与及传统软件工程的流程,可以发现:敏捷把其中没价值的部分大大弱化了,有些甚至是取消了,比如中间文档里程碑评审、状态报告、需求矩阵等等;而对其中有价值的部分,敏捷却是大大加强了,有些甚至鼓励追求极限,比如迭代开发、结对编程、代码规范、TDD等,而且有些敏捷流派还强调纪律。
常常看到有些敏捷的材料中来比对经验主义的流程和已定义流程,说明在软件开发中,当过程过于复杂时,经验主义方式是适合的选择。但这里面存在混淆:已定义流程存在三种解释:
1.第1种是在Cockburn的《敏捷软件开发》第2版中,“理论的或者已定义的过程是一个理解得足够好可以自动化的过程(这个定义与CMMI对‘已定义的’一词的定义完全不同)。经验主义的过程需要人的检查和干预”;
2.第2种是在CMMI中,“已定义过程”的解释是“根据组织裁剪指南从组织标准过程集中裁剪得到的已管理过程,有得到维护的过程描述,为组织过程资产提供过程相关的经验”;
3.第3种是字面意思,形成描述的过程是已定义流程。
显然,与经验主义流程比对的已定义流程采用的是第1种解释。在这种解释下,软件开发中的已定义过程是很少的,典型的有持续集成、每日集成、静态代码检查等,绝大多数过程需要人的检查和干预,无论是传统的需求分析、OOAD等,还是敏捷推荐的TDD、结对编程等等。所以经验主义的过程并不是不要描述,需要而且必须要一定形式的描述。停留在个别团队成员头脑里的经验主义的流程是无法讨论传播的,而只要说出来,哪怕没有写下来,这个流程就已经得到了描述。“只可意会、不可言传”的东西是佛学考虑的问题,不是软件开发考虑的问题。不了解上下文的朋友会很自然的采用第3种解释,那么极可能会误以为敏捷不需要过程描述。
因此这里真正的问题在于流程描述的颗粒度不同。口头表达的流程往往是颗粒度最大的,也是最不稳定的,而传统软件工程中包括进入-任务步骤-确认-退出(ETVX范式)再加上详尽文档模板+评审+度量等的流程提供了很细的颗粒度,被MartinFlower等称为“繁琐滞重”。细粒度的过程有更好的指导性,但显得繁琐呆板,粗粒度的过程往往是抓住关键,但对细节往往指导不够。按照刚刚好(Just enough)的原则,敏捷类流程描述倾向于刚刚好的粗颗粒度,整体上要讲究平衡。
得到描述的流程能够处理大多数情况,一般的颗粒度粗的流程适用性更宽些,但无论如何是不可能把所有未来流程执行时碰到的情况都说明,所以就存在如何遵循流程的问题。显然的在道理上,碰到新情况不能死硬的遵循流程,碰到老情况也不能肆意的破坏流程。虽然恪守约束,避免整个流程体系走向混乱是很好的,但过于教条以至于无视实际情况同样不利于项目和团队。 根据精益的理念,笔者主张:“过程中发现浪费并积极消除重于遵守既定教条”。流程的严格程度要根据团队和团队碰到的实际情况来处理,不要忘记敏捷宣言的第1条价值观:“个体和互动高于 流程和工具”。
在流程方面还有一个问题,就是流程的定义和执行不完全是项目团队级的事情,就算是最尊重团队决策、已经采纳敏捷的组织也会倡导团队之间的经验分享,而有些组织就会直接要求团队采纳其它团队获得的流程,这些流程在不同组织有不同说法,比如有效实践、最佳实践、规范、规程、经验分享、知识共享等等。这里笔者提议“组织整体协同并重于团队自身提高”。
把流程发挥最大作用,必须处理好如图三所示的三对平衡:
图一 过程的三组平衡
说明:图一 只是为形象的说明存在三组平衡,高低位置并不代表哪个更重要,寻找合适平衡点是关键。
从Scrum看,Scrum本身给出的过程略偏向于细颗粒度,比如站会、燃尽图等,而围绕着Scrum的不少培训材料和文章对计划会、反思、评审会等给了很多指导,感觉更加偏向于细颗粒度。在Scrum的咨询、培训和文章中,一般要求遵循Scrum给定的过程,对裁剪Scrum中的元素要慎重,尽量不要裁剪。KenSchwaber对此的描述是,“对Scrum规则的修改,只有在ScrumMaster确信团队足够深入的掌握了Scrum的运行原理,有足够的技能和思维来修改规则时才可以进行”。Sprint计划会上制定的计划通常被假定为某种承诺,作为承诺往往意味着务必要完成。在2011年7月发布的最新scrum指南中,澄清那不是承诺,而是可以完成工作的预测,而且这个预测会在Sprint过程中因为更多信息而改变。笔者认为这个澄清非常好。承诺并不能准确预测未来发展,但却要求(甚至于是压迫)开发人员必须在限定时间内完成某些任务。澄清为预测后,相对容易改变,执行起来不再那么生硬。
从CMMI看,CMMI本身对各个过程域给出了目标、实践和子实践,看起来颗粒度上偏向于细,而且CMMI覆盖的过程范围比几个常见敏捷软件开发流派覆盖的范围要大,所以整体上显得也细。对待裁剪,CMMI在满足目标的情况下是允许并鼓励的,CMMI全部目标的累计字数与敏捷宣言+原则的字数在同一个数量级上,偏向于粗粒度的敏捷类过程描述也是能够符合CMMI要求的。
XP给出了12个实践,比较强调纪律,而水晶方法系列探索了用最少纪律约束而仍能成功的方法,从而在产出效率与易于运作上达到一种平衡。
1. 结束语
敏捷宣言和原则及主要的敏捷流派指出了优化的方向。根据实际情况进行适配,把握恰当的平衡,同时保持对优化方向的追求,保持在"ing"---进行中,持续发现不足并提升,这就满足了敏捷软件开发宣言和原则。平衡、适配是本文强调的关键词。
参考文献:
1,MartinFowler,新方法学, http://www.uml.org.cn/SoftWareProcess/rjgc.12052003.htm
2,Vikas Hazrati, Scrum到底有多教条?,http://www.infoq.com/cn/news/2011/08/rigid-scrum
3,Pete Deemer,经理2.0:Scrum中经理的角色,
http://www.infoq.com/cn/articles/scrum-management-deemer
4,JeffSutherland,Ken Schwaber,Scrum Update:&2011,
原文链接:https://www.f2er.com/javaschema/286982.html