前几天听了worktile的徐老师分享了一些对scrum软件开发管理方法的一些经验和理解,觉得讲的非常好,在此总结一些要点和自己的理解,以免以后忘记辜负了徐老师的分享。
首先科普一下何为scrum,下面是wiki上对scrum的解释。
Scrum是一种敏捷软件开发的方法学,用于迭代式增量软件开发过程。Scrum在英语是橄榄球运动中争球的意思。
虽然Scrum是为管理软件开发项目而开发的,它同样可以用于运行软件维护团队,或者作为计划管理方法。Scrum之间的合作称为“Scrum of Scrums”。
那么先说说什么是敏捷软件开发,从字面上理解敏捷就是快,灵活的的意思。敏捷开发就是一种快且灵活的软件开发管理方法。用一句流行的话说就是“拥抱变化”。
为什么要敏捷
那么为什么要拥抱变化呢,其实这个世界上任何事务都在变化之中,软件需求也是一样,客户也不可能在开发没有开始之前就把需求想的明明白白,在开发开始到产品交付,需求难免不发生变化。而需求一旦变化就会出现问题,修改已经实现的功能成本很高。为什么改动一小下成本那么高呢?这里分两个成本——劳动成本和心理成本。
要理解改动成本先要理解传统项目管理流程。首先在项目开发是以团队协作(一般指10人以上的开发团队,一两人的团队自带敏捷属性)的形式在推进的。有了团队就自然需要管理。那么怎么管理团队呢?最简单直观的方法就是至上而下的推进,由上面的人员负责设计,写好文档(文档越详细越好),分好任务(任务越细越好)下派到实际的代码编写人员。这样其实写文档的时间就会占据非常长的开发周期,然后下派任务,下面的人员需要严格执行被分配的任务。这样的话对于管理者来说是表面上是非常容易衡量执行人员的工作量,并且可以清晰的掌握项目进度。
然而理想很美好,现实很残酷。首先从文档上说,对设计系统写文档的管理人员要求非常高,其实就是凭经验,想象来描述如何实现一个系统。这就有点像考试的时候全凭心算来解一道数学大题,大部分人没有这个能力,不动笔一步步算很难把前后的推导逻辑在脑海中连成一条线。所以难免在系统设计阶段就有一些遗漏,而且设计阶段只有少数几个有系统设计经验的程序员来做,其他初级程序员的劳动力处于闲置状态。
再说任务分配,传统开发团队里面的项目成员一般都是每个人有每个人的特技,比如一个完整的项目一般分UI/UX设计、IOS开发、Android开发、web前端开发、服务器后台开发(还可以继续细分)。这些开发人员一般都是彼此不了其他种类的开发人员所掌握的技术,只能做自己擅长领域的开发工作。初级开发人员拿到了高级程序员写的系统设计文档(有很多甚至详细到用伪代码描述实现逻辑),就可以开始工作了,完全照着文档来实现代码,这样他们不需要动脑袋,完全执行上级的指令,自然也不需要对产品负责,也不关心项目成功与否,项目的目标是什么。
这样就会造成两个问题:
一个功能从设计到实现,需要经过很多人手。这样下面的执行人员要等上面的执行人员的设计稿,很难避免人力上的浪费。并且执行人员也需要一段时间来理解设计人员的意图,这中间还会产生很多沟通成本。(想跟深入理解这种浪费可以看这本书《精益思想》,虽针对IT项目管理的书,但是很详细的讨论了关于生产流程的改进)
写代码的人由于只是照着设计写代码,没有脑力活动,很难调动工作热情,也不会产生对程序品质负责的责任心。
理解到上面存在的管理的问题,那么就知道为什么改动一个功能需要的成本很大了,首先需要从设计到执行,至上到下的需要几个人的工作来实现一个改动,中间就会产生很大的沟通成本(扯皮现象几乎是不可能避免的)。这是劳动成本。其次就是由于代码编写人员对项目是没有责任感且是被动接受任务,所以改动一个功能相当于说他们之前的工作白做,他们避免不了出现埋怨心理。(会觉得PM和客户都是脑袋不好使的SB。单如果他们自己也参与到产品的决策和设计当中所不定就会意识到需求变更时不可避免的)这是心理成本。
敏捷方法的产生就是为了解决上面的问题。首先变化是不可避免的,与其说痛苦的被动接受变化,我们为什么不主动拥抱变化呢。
Scrum
解释了这么多,我来给徐老师介绍的scrum做个总结。
- 思想的转变,拥抱变化!!(这是根本,需要从老大到最底层的共同认识)
- 以客户利益最大化为目标,只做对项目有意义的事儿。
- 团队角色分为scrum master、product owner、developer team。
- product owner 总结backlog item,对产品功能有最终决定权。
- 挑选核心功能来放在一个scrum里,所有团队所有成员评估工数。
- 开发人员自己领task(增加主观能动性)
- task粒度最好控制在一天之内完成。
- 一个sprint结束的产出物必须是一个可演示的demo。
- 开发人员自己演示他们开发的功能。(好处是可以给开发人员压力让他们代码的bug减少)
- 每天站立会议,掌握项目进度,当前遇到的问题。(控制时间在15分钟以内)
- partial release。(后面会解释)
- 理想状态下 developer team的开发人员都是cross functional�的。(俗称全能,从前端到后端什么都能做)
- 一个sprint(scrum中的一次冲刺)结束之后,要开总结会议,总结出需要改进的地方,在下一个sprint中改进,持续改进。
- 敏捷推进过程中不好搞定的人加入到敏捷团队里,感受敏捷过程。
上面都是我从徐老师的谈话内容里整理出来的关于scrum的一些要点,基本上可以认为越上面的点越重要,越是scrum的核心。
一个敏捷项目
现在我自己以一个假想中的案例来讨论在具体实施中如何应用上面总结出来的要点。假设公司接单开发一个有IOS、Android、web客户端的SNS产品。
项目角色
Product Owner
product owner虽然理论上应该是客户,但是一般情况下客户不会到开发现场,所以对于这样一个外包的开发项目,product owner就应该是我们平时说的销售(售前或产品经理),这个人的首要技能是沟通技巧,尽量能全面掌握客户需求,及时反馈客户意见。他在我们所说的Scrum里面应该算责任最大的人,一个功能做与不做他一人有最后决定权。这里所谓的责任最大指的是当项目完成时,这个product owner要确保我们实现的功能是客户所需要的。他其实就是一个“客户代理”,他的职责就是尽可能让他的想法接近客户想法。所以他在团队里做决定的时候要尽量把自己想象成客户。
Scrum Master
scrum master这个人就可以是我们原来所说的技术经理或者PM,他负责搭建开发团队,推进项目进度。这个scrum master和product owner两个人必须通力合作,力气往一块使,共同的目标应该是【以高质量,高效率实现用户需求】。
Developer Team
根据徐老师的讲解,这个团队的团队成员最好都是多面手,一个人可以做项目开发中的各个阶段的工作。比如服务器后端的程序员可以干HTML&CSS,IOS开发可以干服务器后端开发。下面专门用一个小节讨论这个。
设计&测试人员
虽然根据徐老师的讲解,他们的scrum团队里不存在设计和测试人员这个团队,但是考虑到现实项目中Developer Team中的团队成员不可能都是那种高配的多面手,考虑到需要保证项目完成的质量在这里还是需要导入测试团队,设计人员由于也对产品的UX负责,他们其实应该是最懂产品的那群人,所以在项目开发阶段也介入测试工作。
准备开始
这个时候是PO(Product Owner,以下略称PO)与客户沟通,尽量全面的总结客户需求,然后与SM一起沟通(Scrum Master,以下略称SM)项目的工数,初步给客户报价。然后SM就需要找到一到两个DT(Developer Team成员,以下略称SM),进行初期项目的技术调查,把技术难点总结出来(找几个给力的DT先期攻克),把初期的服务器框架搭建好。这时需要一个设计人员先期就开始设计产品的界面(web,native)。项目全面开工的条件是,当这几个前期跟进的人员对产品需求达成统一认识,并且设计人员已经出了客户基本认可的设计稿的时候。
开发阶段
- 组织DT团队,开会给所有团队成员讲解产品的核心需求,还有第一期的设计稿以及功能设计。讨论第一轮sprint首先要开发的功能。
- 把功能需求制作成功能卡片,每个项目成员都挑选他们认为第一轮sprint需要开发的功能并写明理由预估工时数。
- 由PO参考所有开发人员的意见最后确定这次sprint需要开发的功能。
- DT团队成员各自的领取功能卡片。
- 开始冲刺开发。
- 每个功能卡片开发结束之后,发给其他成员review代码。(随时改善代码规范)
- 由开发人员负责向团队全体成员演示他所开发的功能。
- PO负责带领测试团队对产品进行测试,产品上线之前的质量把关有PO和测试团队负责。
- 一个冲刺结束,开总结大会总结项目推进流程。
- 循环执行上面步骤。
关于文档
原则上文档尽量少写。API的定义以及接口规范一定要写。在开发过程中,客户端、前端与服务器后端有任何上的沟通不便需要及时反映给SM,然后由SM视情况判断是否需要追加说明文档,以方便各个开发人员之间的衔接。功能卡片也可视作项目的文档。随时检验开发人员对整体需求的把握,以及产品系统构成的理解,如果有理解不透彻的地方,可考虑补充说明文档(尽量图形化)。
关于Review
项目初期每一个功能开发完成之后要马上review代码,前期开发阶review工作的权重要大于功能开发,以保证团队在代码质量方面能磨合到认识一致,功能开发可以慢慢加速。代码review这个是一个很大的课题,可能还需要专门写一篇文章来讲。
关于会议
原则上尽量避免开会,基本上团队成员每天开一个15分钟的站立会议,团队成员提出开发中遇到的问题,各个功能开发的进度如何。然后PO和SM两个人单独开会看是否有急需解决的问题,例如需要人员调度或者功能变更。
关于部署
尽量实施每日部署,部署环境如下:
- dev: 开发服务器,服务器开发人员与客户团开发人员确认用服务器。(尽量每天部署)
- stg: 一次scrum完成,demo演示完毕的代码部署到pre服务器,这个是PO、测试人员、以及客户都可以访问的服务器,代码bug发生率相对来说比stg应该低。
- prd:真正上线产品的服务器。
版本控制工具上应该维护同名的三个分支(当然还需要创建其他的开发分支,推荐使用git管理代码,分支的创建对于git也是相当轻量的操作),用来部署上面的三个服务器。
客户端的产品应该以同样的管理方式打包,利用deploygate之类的测试应用发布服务来发布。
关于bug反馈
需要专门的课题管理工具登录bug,比如worktile(开发流程中的任务管理同样也可以使用worktile之类的工具)。敏捷team也需要测试团队。尽量让测试人员也接触到开发。自动化测试,持续集成。
关于DT团队中的多面手
现实的团队中多面手是比较少见的,一般情况下一个团队成员只干他擅长的一方面的技术工作。在一个SNS产品的项目里。我们可以把开发团队的成员分为下面几类:
- 设计
- 前端(HTML&CSS 或者JS)
- 后端 (服务器开发 Java PHP .net Python等)
- IOS客户端
- Android客户端
在一个项目中培养能干各方面技术的开发人员是有很多好处的,最重要的一点是产品开发过程中,可以根据具体需求,随时调节开发人员配置,减少下游开发人员等上游开发人员造成的人力浪费。从另一个方向考虑,培养多面手开发人员本身符合员工自己对成长的需求。
具体来讲可以按下面的技能延伸轨迹培养员工:
设计<-> 前端 <-> 后端 <-> IOS客户端/Andriod客户端
总结
敏捷的核心观点是改变,所以上面的流程也不会一层不变。考虑到敏捷会不断的改变上面的开发流程,我也没有把开发流程写的太具体。当然万变不离其中,我们改进流程的宗旨是为了让开发人员能更舒服的干他们喜欢干的开发工作,让彼此间的沟通协作更流畅,让生产效率更高。一切阻碍往这些方面发展的流程我们都可以尝试去掉。理想和现实的差距总是很大,上面谈的都是理想,现实做起来一定不会顺利,不管怎么说,我们需要不断改进,并且有一个量化标准来衡量改变是否对开发过程有益,如果有益就保持这个改变,如果无益就删除这个改变,然后寻求其他的改变,往复循环。我们把它叫做持续改进。
推荐一本书:《精益开发实战:用看板管理大型项目》。徐老师讲课的总结请点击《Scrum到底怎么玩儿?——BB-Talk #001回顾》。