- 项目回顾
- 项目背景
- 成员背景
- 技术背景
- 敏捷实践
- IPM
- Regular catch up with client
- Standup
- Story kick-off
- Pair
- TDD
- Code Review
- Showcase
- CI
- Retro
- 总结
- 术语注释
本文以我在 ThoughtWorks 中的 EUMs 项目经历为依据,覆盖了 ThoughtWorks 日常独立交付项目中主要的敏捷实践。
项目回顾
项目背景
E 项目是一个在线的物资跟踪监控系统。由 ThoughtWorks 团队提供的一套完善的软件交付服务,整个开发过程由 ThoughtWorks 团队负责管理。
成员背景
ThoughtWorks 提供完整的交付团队 (PM* 1, BA *1 , TL * 1, QA * 1, DEV * 4, UX * 1),团队为颇具代表性的敏捷团队,规模 10 人左右。客户团队主要接口人 3 位。
技术背景
项目上的主要技术栈是 Python, Django, AngularJs, PostgresSQL, Docker。DEV 在进入这个项目之前,擅长的技术栈是 Java, Springboot, C#, Android, jQuery。
敏捷实践
项目之所以成功交付,核心在于人,而良好的敏捷流程与实践也是不容忽视的。
早在 2001 年,17 位追求卓越的志愿者聚集在美国犹他州雪鸟独家圣地,讨论一个新的软件开发趋势,它被称作轻量型软件开发过程,后来他们将它定义为敏捷,并且发布了敏捷开发宣言:一种把以人为本、团队合作、快速响应变化和可工作的软件作为宗旨的开发方法。敏捷宣言可以总结为四句话:
个体与交互 优于 流程与工具
客户协作 优于 合同谈判
响应变化 优于 遵循计划
可工作的软件 优于 面面俱到的文档
也就是说,尽管右项有其价值,我们更重视左项的价值。
敏捷开发的核心就是在一个高度协作的环境下,不断的通过反馈来进行自我调整和完善。重点强调的是协作和反馈,协作体现在团队与客户之间的协作,团队成员之间的协作。反馈则是在开发中的任何环节,包括代码质量、自动化测试、部署、项目进度、需求变更、客户验收等,而且反馈越快越好。有句土耳其谚语这么讲的:“不管你走了多远,错了就要重新返回”,所以我们越快得到反馈,就能越早确认自己有没有走错路。如果没有错,我们会更加充满信心。反之,及时做出调整,让浪费? 最小化。
项目中所涉及的敏捷实践主要围绕迭代进行,用一张图概括:
(点击放大图像)
可以总结出以下几点:
- Iteration 通常始于 IPM ,止于 Showcase。
- 每天都会发生事件有 Standup 。
- Pair、TDD、Code Review 穿插在日常 Coding 中。
- Story kick-off 之后,该 Story 就进入了开发环节。
- CI 属于基础设施,通常在一个名为 Iteration0 的迭代完成,也就是正是开发开始之前就应该完成 CI 的搭建。
- Retro 较长一段时间才进行的活动,根据实际情况,1 个月或两个月举行一次。
- Regular catch up with client 也会因项目而异,Daily 或者 Weekly,甚至某些项目可以省略该项活动。
敏捷的宗旨是减少浪费,所有的敏捷实践也都是围绕着高效协作与快速反馈这两个核心理念展开。
IPM
IPM(Iteration Plan Meeting),迭代计划会议主要是跟客户保持沟通与信息更新的一个会议。
敏捷宣言里面有一条:客户协作优于合同谈判。在 Scrum 团队中有一个角色叫做产品负责人,Ta 的核心职责是确保业务需求的清晰和透明,保证开发团队对业务有足够的了解,并将这些待完成的业务需求(Story)按照优先级排列出来,按照任务卡的方式来驱动团队的开发。并在客户需求有变更后能够第一时间告知团队以做出调整。
在我们团队中,这个角色就是一开始提到的 BA。她是 IPM 主要参与人,另外还有 Tech Lead 会一起参与讨论(团队中每一个人成员都是可以参与进来的)。IPM 按照团队指定的迭代的周期,通常是两周,每隔两周跟客户接口人一起约一个时间,主要讨论以下几个方面的内容:
- 下一个迭代的 Story。
- 对下一个迭代的期望。
- 团队的人员可用性。
- 风险的评估总结。
通过这种会议,能够让客户对我们团队状况有一个清晰的了解,而且客户对我们下一个迭代要做的功能有了整体的把控,一起设定好期望,这样也会大大降低风险。
IPM 的主要产出是下一个迭代中完成的 Story,这些 Story 即为下一个 Story 要完成的目标,我们通过敏捷看板工具来管理它们,例如下图 mingle 上位于 Backlog 栏中的 Story:
(点击放大图像)
Regular catch up with client
跟客户建立信任关系是合作的基础,而让客户保持愉悦,也是项目成功交付的助推剂。
Regular catch up with client,即 定期跟客户进行沟通,双方共同商议一个时间(工作时间最佳),一起开个短暂的小会,时间上的成本较低。
Catch up 的主要参与人员是 BA(PM) 和 TL,通过于客户方 Face2Face 会议或者 online 会议进行一个短暂的沟通,沟通内容主要涉及:
- 我们团队昨天的更新.
- 客户昨天的更新
- 确认 Story。如果有变更,能及时作出调整。
- 提醒客户使用我们开发出来的功能,以便我们尽早得到反馈。
- 一些节日的问候,嘘寒问暖,表达我们团队的关怀。
因项目而异,Catch up 实践可以大体分为两种:
- 针对 Onsite 项目 Face2Face 形式。因为跟客户在一起工作,就可以较为高效地组织 Face2Face 的会议,实践证明,Face2Face 是效率最高的一种形式。
- 针对独立交付项目的 Online 形式。因为地点、时差等原因,适当调整 Catch up 的频率,另外选择一个便捷可靠地工具(例如:Fuze, GTM, Skype 等),提前设置好环境并分享给客户相关人员。
通过与客户进行定期的沟通,产生的价值主要体现在客户信任和客户关系方面:
- 首先,让客户有非常强烈的参与感,以及让他们对项目整个进展的把控(他们会觉得自己才是项目的主导者),增强他们的信心以及对我们的信任。
- 其次,让客自己决定功能实现以及及时验收功能,降低了需求变更和打回的风险。
- 最后,则是润滑剂了,能够在客户良好的信任的基础上,保持合作关系的轻松愉快,这会为项目的成功交付使上劲。
并不是每一个项目都会有这个实践,有些独立交付的项目,他们每日站会的时候客户也会参与进来,就不需要额外单独的时间去做这件事情了,而有些项目,因为特殊性,客户可能不希望这么频繁的 Catch up,这时候需要团队灵活变通,与客户一起商讨出一个合适的时间周期,做出一些权衡,让客户自身觉得舒服。总之,Keep 住的一点是:保持跟客户的信息沟通,尽可能早的得到客户的反馈,保持良好的客户关系。
Standup
Standup 是一项成本小收益大的活动,做好它是敏捷的第一步。
Standup,就是每日站会。我听过一个有趣的事情:在敏捷开发方法兴起的时候,很多传统开发模式的团队跃跃欲试,他们选择从 Standup 切入。然后每天早上上班后,大家聚在一起开个会(站着、坐着都有),然后该怎么做还是怎么做。他们会对别人说,我们在搞敏捷开发…
没错,Standup 就是团队在一起快速地开一个会,大家挨个的更新一下自己的状态,更新包含以下几个方面:
- 昨天完成的工作。
- 今天计划做什么。
- 面临什么阻碍。
- 自己手头 Story 的进展。
- 是否存在技术风险。
既然是快速的会议,Standup 的时间就不宜过长,建议 5~15 分钟。最好是站着开会,因为研究表明,当人们坐着开会的时候,会议的时间会被无形中拉长。Standup 的时间安排在工作时间开始后的半个小时最佳(比如 9:00 上班,9:30 开始),这样大家就不用一到公司就急急忙忙的参加 Standup,大家有个缓冲的时间,比如说设置电脑,泡咖啡,沏茶,整理今天的 todo list 等。
没有什么特殊原因的情况下,确保团队成员都要参加,如果一些人因为特殊原因经常不按时到,适当调整 Standup 的时间,但也不宜太晚。
而对于规模很小的团队(3~5 人),也强烈建议执行 Standup,因为它的成本真的很低。
或许有人会觉得:大家天天都在一起工作,沟通如此方便,何必要这项活动? 这有点深处酒巷中不觉酒香的味道了。站会能够给团队带来的价值不容忽视:
- 让大家进入一天的工作状态。
- 清楚自己的 Story 的进展,提醒自己把握好时间,或者激励其他成员的开发进度。
- 让团队成员知道项目其他地方的进展。
- 如果谁遇到不好解决的问题,可以将问题抛出来,大家一起积极讨论解决方案,也能寻求其他人员的技术支持。
- 避免在重复造轮子而耗费时间,让大家知道目前团队中可供复用的解决方案。
- 帮助 Team Leader 了解哪些领域需要更多的帮助,从而更好地分配资源。
Story kick-off
在一个 Story 开始前,确保 BA, QA, DEV 对 Story 的理解达成一致,并严格按照 AC 来验收。当然,前提是 Story 本身是不容置疑的。
Story kick off,指的是对某一个 Story 进行开卡,也就是启动该 Stroy,从而使其进入开发阶段。Story kick off 的时候,通常需要三个角色一起参与:BA、QA 以及要开发该 Story 的 DEV。
Story 由 BA 预先写好,并通过专业的敏捷管理工具进行管理。DEV 在 kick off 的时候,BA 会给 DEV 讲解这个 Story 要完成的功能,以及它的 AC。DEV 如果对其中的描述有任何疑惑,需要及时提出来,当场弄明白才可以正确的去完成这些功能。在后续的开发过程中,如果碰到任何疑惑,随时找 BA 或者 QA 了解清楚,不应该自己猜测着开发,更不可跟着心走。
Story kick off 的核心目的是确保 DEV 开发出的功能都是符合客户期望的。而 Story 本身存在错误并不在讨论范围之内。实际上在开发过程中,也未发生过这种情况,因为一旦客户的需求变更后,Story 卡也会及时变更过来。Story kick off 可以 follow 以下实践:
- DEV 自己先完整地过一遍 Story 的描述。
- DEV 给 BA 和 QA 去讲这个 Story 的功能以及 AC。
- 要能够清晰的讲出来,并且三者达成一致,如果有疑惑,需要当场得到解决。
- DEV 开始开发 Story,并自行将 Story 参照 AC 拆分成很多个子任务列表,然后逐一干掉它们。
最后一个实践严格上讲不是 kick off 环节里面的,它发生在 kick off 后,DEV 自行决定怎么去完成功能。我比较推荐 DEV 在 kick off 后将 Story 划分成子任务列表,按照依赖关系和优先级排序,逐个干掉他们。一些敏捷管理工具 ( Trello , mingle , Pivotal Tracker , teambition ) 都支持这种任务拆分,你还可以很容易的记录与跟踪。
Story kick off 也是一项短时间高收益的活动,因为在我们 DEV 界中,有一句邪门的定律:
猜出来的需求往往是不靠谱的,最终需要打回重做!
所以 kick off 能够有效的避免 Dev 自行臆测业务需求而产生的浪费。除此之外,能够弥补 BA 在编写 Story 的时候技术视角的一些遗漏。
一些项目会引入好的开发实践,比如说 BDD。它能按照人类自然语言去描述一个功能的实现。我们的 Story 描述通常会参照这种方式: as…when…then…when…then。这个时候,DEV、QA、BA 可以在 Story kick off 的时候利用一些测试工具( Cucumber )一起来编写 Story 验收测试用例(主要由 QA 来编写),DEV 负责编写代码来通过这些测试。理想情况下,验收测试用例如果正确完整,当所有测试都通过后,意味着 Story 功能已经完成。而且这种 TDD 的方式,代码出现 bug 的几率也会大幅度降低。
Pair
结对编程的开发速度通常小于简单地将一个人的开发速度乘以 2,但它依然能创造价值:知识的共享,代码质量的提高,缺陷率的降低。
XP 里面提到了结对编程,经过事实证明,它是一项利大于弊的实践。
通俗地讲,Pair 就是两个人同时工作在同一个 Story 上,一起讨论 Story 的解决方案,并编写代码实现功能,一个人敲键盘,一个人看屏幕,穿插着进行。Pair 的小伙伴在快速敲击键盘的时候会伴随一些交流,并时不时停下来讨论说笑片刻,亦或是在欣赏一下自己漂亮的代码。
两个人一起写代码即为 Pair,那么如何进行高效的 Pair 呢,也有一些良好的实践:
- 搭档的选择上,两个人的技能和经验最好是相当的,这样就不至于一个人成为被教育的对象,而另一个人成为键霸。
- 有新人加入时,需要一个经验较丰富的老人 Pair,最好是有良好 Coach 技能的老人,老人尽量只提供思路启发,并让新人多思考和动手实现。
- 经验相当的 Pair 时,可以一起讨论解决方案,并达成一致,然后一个人写测试,另一个人编写代码通过测试,两人同时保持 focus。
- 定期更换 Pair,粒度可以控制在以一个 Story 完成为节点。大一点的 Story 可以 keep 住一个人不动,另一个人进行更换。
- 遇到技术阻碍时,分头并行寻找解决方案,并最终一起决定采取什么方案。
- 当两个人对实现细节的优劣拿捏不定时,邀请团队经验丰富的老人做出建议参考。
在一些很简单的 defect 上,可以不采用 Pair。
Pair 将本来可以并行工作的两个人聚焦在一件事情上,表面上是在降低生产力,实际上它确实是有一定的成本的。而这种付出并不会打水漂,最明显的好处是能够最大化知识的共享(尤其是更换 pair 的场景下), 包括业务知识的共享、技术方案共享、解决问题思路的共享,这一点尤其体现在团队有新人融入的时候,通过 Pair 能够快速带领新人成长起来,提高整个团队的战斗力。另一方面可以提高代码质量,Pair 实际上是两个人一直在不停的做 Code Review ,两个人的思维碰撞能够避免很多代码小聪明和不好的编码习惯。
有些时候,因为项目进度的紧张,Pair 并不会这么理想的被落实,团队可以进行灵活的调整。如果 Pair 的时间减少了,可以通过加长 Code Review 的时间来做一些弥补。
TDD
TDD,测试驱动开发,这项人人都称赞、却很少有人真的去做的活动,不应该只是一个被供奉起来的神。接地气,再接地气一点。
TDD,即测试驱动开发,强调的是测试先行。TDD 是一个存在争议的主题,因为在一个连测试的没有的代码库中(多数客户也不关心测试代码,他们通常只想要看得到的功能),它的立身之本就不复存在了。我经历过只有纯手工黑盒测试的项目,没有单元测试、没有集成测试、没有 E2E 测试(测试金字塔, Martin Folower ),所以TDD 无从谈起。我也经历过客户要求测试覆盖率的项目,有专门的测试覆盖率工具( coveralls ) 来检测代码库,有的甚至集成在 CI 上作为一个硬性指标。
所以,TDD 必须在一个有测试的项目中去讲。它跟我们先实现功能代码后添加测试的过程恰恰相反。我们根据对业务理解,先写一些测试(E2E,Integration, Unit),此时得到运行结果为红色(测试运行失败),然后编写业务代码让其变绿(测试运行成功)。
当然,TDD 实践存在一定的门槛,TDD 更多地考察一个人的设计能力,所以需要有一定经验的开发人员,而新人往往是很难做到这一点,但这不应该是新人不去尝试 TDD 的借口。
在实际项目中,可以根据团队自身的条件,灵活采取 TDD 去编码。就我个人的经验而言,TDD 编码的时候刚一开始的时候并不是那么顺手(因为 TDD 更偏重设计),心里会觉得比较耗费时间,最终 Story 的完成时间相差无几,而 TDD 除了有效地降低缺陷率,还有以下三个方面的好处。
- 从宏观把握 Scope,开发人员不会在开发的过程中扩大或偏离 Scope。举个例子,开始一个功能点时,一上来添加一个 E2E 测试,整个 Scope 在此时就被框定,然后再细分到内部实现,最终以通过这个测试来完成这个功能。
- 提高代码的设计。当我们先写测试的时候,就会考虑到被测试的对象要尽可能被方便的测试,此时我们会尽可能的改良我的的 API 设计,以便利于测试,这样一来,我们写出的代码更具有可测试性,这样的代码往往具备较高的质量。
- 确保功能不会被遗漏。我们一开始更多关注的是业务,而不是代码的实现细节,此时写出来的测试会更全面的涵盖不同的 Case。
Code Review
不可否认的一个事实:人人都爱整洁的代码。而一个人单独编码难免会耍一些小聪明,或引入一些自身习惯难以察觉的不良代码。Code Review 能让你提高警惕,并改善代码的质量。
Code review,检查代码,也叫代码审查,就是开发人员凑在一起来检阅彼此所产出的代码。看看有没有新的代码坏味道,看看有什么不合理的设计甚至是错误的设计,等等。
既然是开发人员凑在一起审查代码,那么 Code Review 会产生一定的时间成本(根据团队的规模 1~2 小时 = 5~10 个开发人员),所以需要一些良好的实践来确保 Code review 的高效产出:
- 团队一起拟定一个开始时间和时长,并落实到位,保证团队成员的参与度和 Focus。
- 短时间的描述自己的 Story 业务,主要 Focus 在代码上。
- 持续跟踪记录,并获取反馈。这需要有一个人记录问题(可以按天轮流),结束后交给 Owner 执行更改,并且下一次 Code Review 的时候先过上一次的更改。
- 必要的时候拉长时间,条件允许下建议在一个有大显示器的会议室中进行。
另外,从团队规模和时间安排上,可以遵循以下两个原则
- 对于规模很小的团队,可以适当减少 Code Review 的时间和频率,如果团队经常 Switch Pair,也可以适当减少 Code Review 的时间。
- 安排在下班前进行。一方面,大家经过一天的高强度的思考与编码,适当停下来,看看其他人写的代码,同时将自己代码讲解出来,还能意外的获得一些灵感,或许能解决自己面临的阻碍(你所面临的问题可能已经被其他人解决了)。另一方面,如果这个时候发现代码的坏味道,需要改进的地方,下班后可以花少量时间作出更改。
长期的实践证明,Code Review 能带来的好处有:
- 让每一个人提高警惕:自己写的代码并不是只有自己看的,所以要督促自己做好。比如规避不想写测试,代码耍酷等。
- 共同找出代码的坏味道(命名规范,代码整洁,API 内聚性,面向对象设计),及时做出改正,提高代码库的质量,有助于后期扩展和维护。
- 让团队成员知道他人在做什么以及怎么做,分享好的编码习惯和技术实现,有助于团队整体进步。
Showcase
不管客户有多忙,也要定期让客户确认自己的期望是否得到满足。在签订合同前,要跟客户达成一致:Showcase 的地位不可动摇。
Showcase 就是给客户演示我们上一个迭代已经完成的功能,它的宗旨是及时得到客户的反馈,确认团队的产出是否满足客户的期望,降低需求变更返工的风险。
Showcase 从项目开始时周期性地进行,并直到项目交付。这个时间间隔是基于团队设定的迭代周期,我们团队是两周一次。团队跟客户安排一个远程会议(如果是在客户现场,一些参与讨论效果更好),主要涵盖了以下内容:
- 跟客户确认上一个迭代的 Story 列表。
- 项目目前的交付状态。是否正常进度,会不会延期。
- 演示上一个迭代完成功能。在线系统演示,需要一个 staging 环境。
- 客户对功能确认,对达到期望的 story 签字,反之。我们记录下问题,并修改,再次确认签字。
Showcase 的目标是客户,需要针对不同的客户有不同的策略。如若客户觉得每两周一次过于频繁,团队可以变通调整迭代周期,通常建议的是 1~4 周,不宜太长,太短也没什么效果,至于如何权衡这个时间,有两点可以参考:
- 在探索中找到适合团队的迭代周期,如果发现每个迭代时间不够用,要么是 story 划分太大,要么是迭代周期太短,这时需要根据几次的平均结果做出调整,适当扩大迭代周期,或者更合理的拆分 Story。
- 如果 Showcase 的时候功能背离了客户的期望,通常是因为迭代周期太长。因为用户的需求以及团队对需求的理解都在随着时间的推移而变化,导致发布时的产出并不是客户需要的。这个时候,可以考虑适当缩短迭代周期,让反馈来的更快更舒缓一些,而不是更慢更猛烈。
试想一下传统瀑布开发模式下,一个功能的演示通常安排在在某个里程碑节点,此时项目或许开展了半年或一年甚至更久,客户这个时候见到自己的系统,简直会惊叫起来,原来这压根不是他们想要的东西(因为客户一开始都不知道自己要什么),即便开发团队严格按照预先的设计文档。这是一种时常发生的灾难,它导致大量的浪费,且很难挽救。
敏捷开发可以规避这种灾难性事件的发生。而 Showcase 在敏捷开发中是一个不容忽视的环节,它契合了敏捷宣言中的拥抱变化优于遵循计划。Showcase 能够让团队在每个迭代完成后及时从客户那得到反馈,对变化做出快速的响应,避免了劳动成果的浪费以及方向的偏离,也能最大化让客户的期望得到满足。
为了达到更好的 Presentation 效果,Showcase 通常提前准备一个总结性的 Slide 来引导整个过程的推进,结束后该 Slide 即为产出的一部分,另外也会有一封总结性的邮件来跟踪记录 Showcase 的结果。
CI
没有 CI 的项目开发是在耍流氓。CI 在 Agile 中是一项最基础的设施,它通过自动化来提供有效的反馈机制以及高效的部署,大大降低代了码集成和项目交付的风险。
CI,持续集成。在敏捷开发中,它是一个项目开始前必须搭建起来的基础设施。当代的软件开发项目中,几乎没有项目是只有一个人在开发的。超过一个人就形成了团队,每个人同时并行开发不同模块的功能,这就涉及到代码的集成,所以代码集成是几乎所有开发团队都要面临的问题(一个人的开发项目不在本文范畴中)。
持续集成跟团队开发人员独立开发没有冲突,相反,借助一些工具( Jenkins , GoCD(ThougthWorks 开发) , Travis CI ),它能快速的对我们开发人员提交到代码库的代码作出反馈。开发人员每天都在代码库提交代码,版本控制工具(比如 Git )在提交前必须更新代码库最新的代码(解决冲突,代码合并,应用更改),然后将代码提交到代码库中。这个过程是代码集成的第一步,最重要的是如何确保这些集成是可靠的,以下是一些关于 CI 的良好实践:
- 开发人员对自己编写的代码添加足够的测试覆盖率。这是基本,基本最无敌:一来验证代码的正确性,二来防止被误更改。
- 每个人提交代码到代码库之前在自己的机器上保证单元测试都能通过,很耗时集成测试和 E2E 测试可以更多的交给 CI 去跑。
- 借助一些 CI 工具(见上文), 将代码集成的结果反馈展示在团队所有人都能看到的 Dashboard 上,一定要大家都可以看到。
- CI 定期检查代码库的更新,只要有更新,就要运行所有的测试。这里有个权衡:不耗时的单元测试每次全部运行,集成测试也要频繁的运行,耗时的 E2E 测试可以稍微执行少一点(比如设置夜间执行)。我们这个项目,是每次检查到更新就会运行所有的测试(单元测试 + 集成测试 6 分钟,E2E 测试 30 分钟)
- CI 如果没有通过,所有人都应该停止向代码库中提交代码,直到 CI 被修复,所以如果 CI 挂了,能够及时通知相关开发人员,要第一时间修复。
- 所有测试通过之后,CI 负责自动化部署到不同的环境(Test,开发团队测试环境;Staging,客户 ShowCase 环境;UAT 和 Production,用户验收测试环境和生产环境,通常开发团队没有权限),并正常启动所有的服务。
通过这些实践,CI 能带来的价值也是相当可观的,主要体现在五个方面:
- 减少重复的过程。CI 通过自动化,将一些需要重复执行的操作(代码审查、编译、测试、构建、部署)自动化管理起来,大大减少了重复的过程,节省了大量的时间。
- 降低风险。开发过程中,每天进行多次集成,并且添加了足够相应的测试,每次集成 CI 都会快速检查代码中的缺陷并提供及时的反馈,降低了未知的风险。
- 可视化。CI 提供了大量真实且最新的数据,能够让我们关注当前集成的趋势(例如构建时间、构建失败比例、测试覆盖率等),有利于有效决策。
- 增强团队的信心。每次构建的结果都是公开透明的,所有人清楚地知道自己的每次提交改动对软件所造成的影响。
- 随时随地可以生成可部署的软件(CD)。对于客户来说,可以部署的软件产品是最实际的资产,而 CI 让我们可以在任何时间发布可以部署的软件。
可以借助一些工具,比如 Chrome 插件 BuildReactor 可以将 CI 的多个 Pipeline 集中展示出来。
Retro
团队专注于交付目标,埋头干活的同时,也要懂得停下来总结过去,并更好地抬头看路。
Retro 是 Retrospective 的简写,即回顾。团队通常以回顾会议的形式进行,大家坐在一起,对过去的这段时间里,我们 Team 的工作状态(团队合作,技术实践,团队氛围等)做一个总结,它有一点基本思想:对事不对人,大家思想自由 Open。如何做到这一点,下面是我们 Team 的实践:
- 确认构建安全的环境。什么意思呢?就是每个人都是觉得当前的会议是可以自由发表意见的,而不是因为某些人(比如说不友善的 Leader)而不敢发表意见。开始前每个人对安全系数打分,1~10 分,如果平均分数偏低(比如低于 6 分),需要将 Leader 从会议中"驱赶出去",直到大家觉得安全了才好。
- 建立几项总结指标(Well, Less Well,Suggestion,Action),大家分别对前三项提出自己的看法。第四项是综合所有前三项的结果总结出来后面要做的事情。
- 使用 Sticker 纸片,最好是用马克笔写(这样一张 Sticker 就不能泛泛无边的写),一张 Sticke 写上一个点的内容即可。
- 编写 Sticker 内容的时间控制在 5 分钟以内,每个人自己将 Sticker 按照分栏贴好,然后 Facilitator(通常是 PM 或 BA)开始带着大家过每一栏的 Sticker,对 Less Well 栏中,将同一类的问题归纳起来,总结出相应的解决措施。
- 将 Action 栏中的 Sticker 指派 Owner,并落实。
- 如果跟客户关系融洽且相对容易参与进来,可以将客户 Involve 进来,然后一起构建一个安全的环境(有可能因为大家的打分较低,客户不得不“出场”,所以客户参与不是必须的)。
说得天花乱坠,没有行动,犹如竹篮打水。Retro 这个环节最核心的产出物是 Action,团队共同一致商量出来的措施,有没有效果就在于行动了,所以 Action 分配了 Owner 之后,一定要跟踪这些 Action 有没有落实执行。一方面,需要 Owner 拥有高度的责任心和执行力,尽职将这些 Action 落实执行。
Retro 的细节因团队而有些差异,而它的理念是一致的:总结过去,做的好的方面继续保持及加强,做的欠佳的方面一起讨论改进措施,并尽全力落实。Retro 让团队在实践中摸索出适合团队的最佳实践,引导团队和个人不断自我完善,追求卓越。
总结
敏捷开发实践不只是拘泥于这些流程形式,在形式背后,我们应该深入思考这些实践是否减少了浪费?是否促进了高质量的交付?每个团队都是不同的,不必拘泥于这些流程形式,而是要追求这些流程产生的真正价值与意义。
术语注释
- PM:Project Manager,项目经理
- BA:Business Analyst,业务分析师
- TL:Technical Leader,技术领导
- QA:Quality Assurance,测试人员
- DEV:Developer,开发人员
- UX:User Experience,用户体检设计师
- AC:Acceptance Criteria,验收条件
- UAT:User Acceptance Test,用户验收测试
- Retro:Retrospective,回顾会议
- TB: Team building,团队建设
感谢徐川对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们。
评论