敏捷无它,唯持续改进
一、背景介绍
这个案例发生在我曾经所在的C公司,我是两进两出这个公司,这个案例主要是讲述我第二次进这个公司后一年之中所发生的一些事情,以及我的一些思考。
那一年,距离公司引入Scrum已经将近3年,喧嚣过后,Scrum和敏捷何去何从?公司经过3年变得敏捷了吗?敏捷的本质又是什么?
二、我与敏捷的第一次亲密接触
2006年我第一次进C公司。这个公司有好几条产品线,做的也都是企业应用软件开发,在上海和南京均有研发部门,而我是一直在上海工作的。
2007年的时候,公司的VP开始在我们团队推广Scrum,现在想起来,在国内应该算比较早的了。那时候除了那位VP,其他人基本都没听说过Scrum这个东西,而公司的研发团队不少,所以刚开始并没有很全面地采用Scrum的所有实践。像我们团队,所使用的实践首先是迭代、还有估算、每日站立会议,基本就这些了。
我记得我们的前几个迭代是这样的。
我们挑出要完成的一些特性集合,然后估算出需要3周还是4周来完成,定出这个迭代的周期(也就是说我们的迭代并不是时间固定的)。我们的估算,以0.5人 天为最小单位,每个人独立估算,然后算出平均值就是最后的结果。听上去过于简单?后来有了改进版,那些估算比较准确的人,在下一个迭代的估算中会增加权 重,而不准确的人会减少权重。这样的估算机制,现在想起来,还是很准确的,我们的迭代基本上都在估算的时间内结束,偶尔也有失败的时候,我们就延长迭代!
每个迭代还会选出一个领导(由几个资深程序员轮流担任),这个领导的任务是尽量保证迭代完成,然后在迭代结束时向PO来做演示,有点ScrumMaster的意思,可大家都对Scrum不熟,所以也不能算。其实那时根本没有ScrumMaster的提法。
迭代开始后,由这个领导对要完成的特性(还没有Story的概念)进行优先级(High Level)的设计,一些重要类的实现,如果有必要,还会画出UML图。然后分解出所有要做的任务,分配给组员。因为我们早就有了日构建(Daily Build),所以领导还需要负责隔三差五地检验各个日构建是不是被成功集成起来,因为在迭代的最后一天,他需要向PO 演示所有的特性。
迭代刚开始一两天领导在做优先级(High Level)设计的时候,其他人在干什么呢?在修复一些Bug,或者上个迭代里PO的一些反馈。
由于我们的迭代基本上都是一个月,加上那个VP不久就调到南京办公室去推敏捷了,我们并没有经历很多迭代。所以后面也没有精彩的故事发生。
基本就这样了,没有白板,没有用户故事,没有ScrumMaster,没有回顾会议……用现在的眼光来看,它是彻彻底底的伪Scrum或者Scrum-but,每个迭代里都是一个瀑布式的过程。那么,它是敏捷吗?
三、敏捷原来是这样的
2009年初的时候我离开了C公司,加入了Daniel Teng(http://www.danielteng.com/)所领导的一个不大的公司,在里面工作了10个月(10个月后我回到C公司,加入另一个部门,历时1年,就是本案例所要讲述的1年)。这10个月给我的影响非常大,身临其境了才知道,原来敏捷是这样的。
首先公司的布局“杂乱无章”,办公桌被摆成了“骨头”形状,每块骨头可以坐六个人,这六个人基本上就是抬头即可看到对方,整个办公室就是六七块骨头组成的。您猜对了,每块骨头的那六个人,就是一个Scrum团队。
办公室的门口摆着一个大白板纸,上面一张白纸上是手写的当月的日历,我上班第一天看到日历上的当天写着“John Cai on board”,John Cai就是我了。后面有些天写着“某某某请假一天”。这是干啥的?这是Informative Workshop的一部分。
旁边的墙上一个大的液晶显示屏,上面绿绿的一些英文字,这是CI(持续集成)墙。如果谁的代码签入引起CI红了,不仅立刻显示在液晶屏上,还会有声音发出来,全公司都听得到,这时就会有人去修复,这个人的名字也会在液晶屏上显示。当然这不是液晶屏的唯一功能,下班后,它就是用来玩Wii的了。
我记得上班第一天,Daniel问我吃早饭没有,说厨房有牛奶、饮料、各种零食。我刚开始以为是周一福利,但其实在我待的10个月里,零食就没断过。每周一、三、五另外增加水果时间,所有人轮流负责买水果,洗水果,然后发到每个人的桌上。
很多书,敏捷的、技术的,所有跟工作相关的,如果这些还不够,只管自己去买就行了,买回来放公司还是放家随你,一律公司报销,不需审批,完全自主。
每个人都在讨论和实践着Pair、TDD等工程实践。各种新技术也是茶余饭后的谈资。
每周五中午都有Tech Talk,公司买来中午饭,除了主讲人需要提前吃饭,其他人手里拿着鸡腿、比萨或者盒饭,边吃边听。
每个月每个人都有固定的团队建设费,一般一个Scrum团队的人会把这些钱合在一起,自行组织出去活动,我就是用这样的机会和团队一起看了电影《2012》。
……
在这样的环境中过了10个月,原来C公司的主管让我回去,说实话,到那个时候为止,我在这个公司所获得的大多数是感官认识,有很多事情知道了他们是这么做的,至于为什么要这么做,这么做背后的价值观、原理,还是缺乏更深的体会。
原公司主管叫我回去做技术主管,“技术上带带公司一个比较年轻的团队”。可是我心里想的不止是技术上“带带”,我想把这里学到的关于一切敏捷的好东西,都带回去。
四、第一个挑战
2010年初,我回到了C公司,加入了另一个部门。因为原先的主管换到这个部门做老大了,这个部门是做人力资源管理系统的(以下简称HRP),由3个Scrum团队组成,其中两个在上海,另一个在南京。上海的两个团队很多都是开发这个HRP产品的元老,而南京的那个团队,相对比较年轻,也没有元老级的人物(事实上南京办公室本来就是晚于上海办公室建立的),技术上相对薄弱一些,主管叫我回来就是技术上带一下这个南京团队。
这个团队由5个开发、1个PO、2个QA组成,开发都是男的,其余都是女的,是个很合理、很标准的Scrum团队。而且都比较年轻,朝气蓬勃,自信心十足——这就是我面临的第一个挑战。
我心 里的目标很明确:要提高这个团队。如果是一个自知有很多问题的团队,比较好办,因为它已经是接纳的心态。可是面对一群自信心十足的年轻人,他们认为一切都 很不错,我怎么去提高他们?首先我不能直接告诉他们:你们是需要提高的。他们对我这个空降的技术主管本身就心存芥蒂,有些若隐若现的抵触情绪。于是我决定 要做的第一件事是让他们认可我。
五、团队的好奇心
我用的方法很简单,是从Daniel Teng身上学到的:我每周会从我读过的好的博客文章中选出5~10篇,以每周链接(Weekly Links)的形式分享给他们。邮件里特别注明了是分享,没有强迫他们读的意思,就是同事间的平等分享而已。
这种小小的举动其实带来很多好的东西:
- 我做出了表率,他们心里清楚,我要每周挑出几篇来分享,我读的肯定至少是几十篇。这种表率对建立一种学习氛围是很重要的。
- 我发的基本都是英文博客,很多技术和好的想法都是从国外源起的,很多国外博客确实质量高得多,相对比较有权威性,同时这是对他们的一个暗示:技术人员要尽量接触国外第一手资料。
- 这是 一种很好的开阔眼界。既然是英文博客,我相信即使我发给他们,他们不一定都看,但我尽量挑一些对他们来说比较陌生的、可是又很重要的话题。他们光看看标题 也是有收获的,至少打开了他们的视野。对于一个比较封闭的团队(我相信很多没有学习氛围的团队都是这样),打开一扇窗,吹进去一缕风,就是个很好的开端。
- 由于我分享的Lean、NoSql、DDD、TDD、Pair Programming,OO的SOLID原则等,这些都是这个年轻的团队几乎听都没听过的概念,一个很重要的东西被激发了:好奇心。
- 有了好奇心,这个团队就处于“可被激活”的状态了。
六、更多挑战
我的聚焦点自然还是技术方面,慢慢观察下来,情况很不乐观:
- 3个Scrum团队各自负责开发几个独立的模块,这是正常的,但他们各自都有一个独立的.NET solution文件,每个组的solution文件都只包含他们所负责模块的project。也就是说他们工作在不同的codebase上。这样团队就没有交流,我是指没有代码层面的交流。
- 使用微软的VSS作 为源代码管理工具。服务器在上海,南京获取代码奇慢无比,要好几个小时。于是他们是这么运作的:每周一由南京某同事花几小时时间把最新代码获取下来,然后 复制给南京其他同事,这一周,南京团队就在这个“最新”代码上工作了,只签入,不再获取。什么?这样容易有代码冲突?没事,他们使用——写到这里我决定要 融入他们团队了,以下不再使用“他们”,而是“我们”——我们使用独占式检查方式,保证每个人的工作都没有交集,也就没有冲突。这让信奉CI的我情何以堪?
- 南京团队对技术架构没什么发言权,上海定好了约定俗成的架构,南京照做就是了,他们按部就班地照着架构干活:ASP.NET WebForm page的code behind文件调用service,比如AttendanceService.GetAttendance()方法,而AttendanceService.Get Attendance()什么也不做,只是调用IDAO.GetAttendance()方法,IDAO的方法里就是SQL了。于是我看到一大堆什么也没做的Servcie(还有他们的接口),而业务逻辑很多都表达在SQL语句里。
- 没 有单元测试,可是有些成员会告诉我有。因为的确有若干自动化测试,可是那些自动化测试都必须连接数据库才能运行,运行得慢,所以很少运行,日构建只是构 建,没有运行这些自动化测试。我试着运行几个,可能由于数据库里的数据已经变了,所以失败了,我之所以说“可能”,是因为我没有深究,没法深究,自动化测 试的代码也是一大段,看也看不懂,不知道它想测什么。
- Sprint(迭代)不能按时结束。上海团队是有QA Sprint的,也就是QA的Sprint落后开发的Sprint一个周期,他们在Sprint内测试开发人员上个Sprint开发完成的东西。
- 技术上,大部分程序员其实都没有什么面向对象设计能力,面向过程式的代码到处可见——这即使在其他公司,也是很普遍的现象。
……
七、团队的惯性
现在回过头来想,我那时看到的那些问题,难道没有人看到吗?我相信不会,尤其是上海团队中有几位还是很不错的,可是为什么那些问题一直存在着呢?
我想这就是一个团队的惯性,或者一个团队的文化。当日复一日地按着团队的惯性做事时,我们每个人就不知不觉地被“体制化”了。
而我现在觉得,主管的一个作用就是要设法建立起这样的一个机制,让团队从惯性中挣脱出来,一个办法就是自己走在前面,让别人愿意跟随——这就是主管(Lead)和经理(Manager)的一个区别,Manager是“让别人跟随”,少了“愿意”二字。
可是怎么培养自己的领导力(Leadership)?我当时并没有多想,我着眼于怎么取得南京团队的信任,让他们愿意跟着我的思路去做一些改变。
八、镜子
陷入惯性的团队往往自我感觉良好,或者至少对一些问题都习以为常见怪不怪了。这时我能做的一点就是给团队一面镜子,让它看到自己的不足。就如同我们每天出 门前都要照照镜子,看看脸上有没有饭粒,发型会不会很怪,而且这面镜子还必须是高清的,最好是任何一点瑕疵都能看得一清二楚。团队同样如此。
我给南京团队的第一面镜子是一个代码分析工具,叫NDepend,这是一款.NET下检查各种代码指标的工具,比如圈复杂度、包的稳定性和依赖性分析,还有类和方法的代码行数统计之类的。南京团队一个同事之前跟我说:他们几年前的代码比较差,但现在的模块采用了新的架构(就是Service啥也没做,直接调用数据访问层那一套),已经比较好了,言下之意颇为自得的样子。
我就先用NDepend分析了一下他们新的模块代码,告诉他们圈复杂度有点高,类有点大,同时在那周的Weekly Link里,我着重分享了OO里的几个设计原则,“单一职责原则”、“依赖倒置原则”之类的,又提到了单元测试的几个原则,比如不能连接数据库,而他们的代码要想测试,没有办法不连数据库。
这些镜子照出来的瑕疵,为我的下一步计划提供了很好的切入点。那就是“单元测试”。
九、从一开始就要高标准
我在后来读到过一篇文章,讲的是大家总结下来的敏捷转型的十大建议,其中一个建议就是“从一开始就要高标准并且一直保持”,所谓高标准并不是要求团队一口吃成胖子,一下就达到高标准的要求,而是对团队一开始就设置高期望值,让团队拥有持续改进的动力和一个愿景。
无独有偶,我前一阵有一天在公司翻到一本关于英语教学的书,里面第一章的标题就是“Setting High Academic Expectations”,第一句话是“high expectations are the most reliable driver of high student achievement(高期望值是带给学生高成就的最可靠的驱动力)”,教学如此,敏捷也是如此。
因此我想推单元测试,我一下就给他们来个高标准,就是TDD。
十、TDD的争议
TDD在网上是有争议的,有人视之为一个团队的必须实践,也有人认为它太浪费时间。我把它当作一个高级程序员和初级程序员的分水岭。我到现在仍然认为:至少在企业应用软件行业(由于我本人毕业至今做的都是企业应用软件,从没涉猎其他领域,所以对其他领域不妄言),一个没有掌握TDD的程序员,就是初级程序员,不论他技术如何。
也许有人不以为然,认为有不少技术很好的程序员也不写单元测试,更不会TDD。可是仔细想想:这种人所谓技术很好,是他写的代码很有可读性?还是他只是对某些框架、工具或控件非常熟悉。
为什么我提到“可读性”?因为一个企业应用软件,它的维护成本往往是开发成本的十几倍乃至数十倍以上(只有那些可读性非常好的软件,这种比例能在十倍以 内),再考虑到我们每天在现有的代码库上写代码,都要先读读原来的代码。也就是说,一个团队花在读代码上的时间往往是写代码的时间的百倍以上,一点不夸 张。所以一个好的程序员,写出可读性、维护性好的代码,比解决一个技术难题重要多了,而且说实话,在企业应用软件开发中,真没有什么很难搞定的技术问题, 最难的是复杂无比又千变万化的业务。
为什么我在说TDD的时候提到“可读性”?网上有些反对TDD的人把TDD当做测试来说事儿,真是令人失望。这些人不知道TDD首先不是关于“测试”的,它是关于“设计”的。这句话我经常在同事面前说,但同时我也知道,一个没有尝试或掌握TDD的人,不会理解这句话。
本文节选自《敏捷开发一千零一夜》一书,王立杰 主编,电子工业出版社出版
相关推荐
### 软件工程中的敏捷评估与持续改进 #### 第一章:软件工程概述 - **软件工程概念**:软件工程是一门集成了多种学科知识和技术手段,旨在提高软件产品的质量和开发效率的学科。它主要关注于软件生命周期的各个...
通过阅读《敏捷实践之持续集成》的相关资料,如“持续集成.mm”、“敏捷实践之持续集成(V1.0).ppt”以及“持续集成测试.txt”,我们可以获取更多关于如何在实际项目中实施和优化持续集成策略的深入见解和案例研究...
《持续集成:软件质量改进和风险降低之道》一书深入探讨了如何在IT行业中通过持续集成来提升软件质量并有效管理风险。持续集成是敏捷开发方法的重要组成部分,它强调频繁地将开发人员的工作成果合并到主分支,以尽早...
### 软件工程中的敏捷开发与持续集成 #### 第一章:软件工程概述 - **定义**:软件工程指的是应用系统化、规范化且可度量的方法论来处理软件的开发、运行及维护过程。 - **特点**: - 确保项目遵循既定步骤进行;...
这些要素强调了测试人员与团队其他成员协同工作的必要性,以及在敏捷开发过程中持续改进和学习的重要性。 对于测试人员来说,适应敏捷团队意味着要具备快速学习和适应变化的能力,能够以开放的心态接受新的测试方法...
CMMI.敏捷整合开发:更快改进性能的案例与实用技术].Paul.E.McMahon.扫描版
敏捷原则包括:持续交付、欢迎需求变更、促进团队成员间的密切合作、追求优秀技能与良好设计、以及持续改进。 #### 三、发展:Scrum框架 Scrum是一种遵循敏捷宣言价值观和原则的软件开发框架,其核心在于短期迭代...
敏捷软件开发是一种以人为核心、迭代、循序渐进的...敏捷方法论不是一种固定的做法,而是一种适应变化、持续改进的态度和方法。通过这种方法论,团队能够更好地管理项目中的不确定性,从而提高软件开发项目的成功率。
《软件测试与持续质量改进(第3版)》是一本专为软件开发人员,特别是致力于提升产品质量和测试效率的工程师量身打造的书籍。书中详细阐述了软件测试的重要性和实施策略,以及如何通过持续的质量改进过程来提升软件...
### GitLab + Jenkins + SonarQube 敏捷开发持续集成环境 #### 一、敏捷宣言与持续集成 - **个体和互动高于流程和工具**:强调团队成员之间的沟通与协作,比制定复杂的流程和使用高级工具更为重要。 - **工作的...
这需要在敏捷团队中建立一种平衡,既保留敏捷的快速响应能力,又引入CMMI的严谨性和持续改进的文化。通过定期的评审、审计和反馈循环,确保敏捷项目的质量和效率得到提升。 总结来说,敏捷测试与CMMI的结合要求我们...
- 定期举办敏捷研讨会或工作坊,分享最佳实践,持续改进开发流程。 ### 结论 华为从IPD到敏捷开发的转变,不仅是一次技术上的革新,更是企业文化、组织结构乃至思维方式的全面升级。通过这一系列的变革措施,华为...
### 用敏捷方法实施基于CMM的软件过程改进 ...总之,无论是采用CMM还是敏捷方法,关键在于找到最适合组织现状和发展需求的过程改进策略,持续不断地进行优化和调整,以实现软件开发过程的有效改进。
敏捷成熟度模型(Agile Maturity Model,简称 AMM)是一种评估敏捷团队成熟度的模型,它通过 8 个维度和 5 个级别来评估团队的成熟度,并帮助团队找到持续改进的方向和目标。该模型建议每季度团队进行一次约 2 小时...
9. **敏捷质量管理**:讨论敏捷项目中的质量保证活动,包括缺陷管理、度量和改进。 10. **敏捷测试中的沟通与合作**:强调在敏捷环境中,跨职能团队间的有效沟通和协作对于成功测试的重要性。 通过阅读《敏捷软件...
故事是当前版本的重点,哪些是次要的。测试人员根据这些 user stories 来编写测试计划和测试用例,确保优先级高的功能得到充分的测试...同时,敏捷测试强调团队合作、早期介入和持续改进,以适应不断变化的项目需求。
敏捷开发是一种适应性极强的软件开发方法论,它强调灵活性、快速响应变化以及团队间的高效协作。在敏捷开发中,没有预设的、固定的流程模板,...因此,敏捷开发是一种持续改进和自我完善的哲学,而非僵化不变的框架。
在本次分享中,刘天斯(yorkoliu)作为13年互联网运维经验的专家,结合在腾讯等公司的实践经验,对DevOps持续改进进行了深入的解读。他首先提出自己的DevOps观,认为DevOps不仅是一种文化,也是一种技术、流程和人。...
2. **敏捷原则**:包括频繁交付可工作的软件,欢迎改变,面对面的沟通,以及持续优化等,旨在鼓励团队灵活应对变化,保持高效沟通,并持续改进产品质量。 3. **Scrum框架**:Scrum是最常见的敏捷开发框架,由角色...