写点什么

敏捷初哥忏悔录

2010 年 11 月 12 日

在职业生涯的大部分时间里,我都是按照瀑布模型的方式进行工作。不久之后,我加入了 Xebia,开始以敏捷的方式做活。特别是,我们一直把遵循 Scrum 和 XP 方法论与 TDD 相结合作为重点强调的实践。从瀑布模型到敏捷的转变,就像从宇宙中的一颗行星突然跨到另一颗一样巨大。一旦完成这种转变,你的世界将发生翻天覆地的变化,你的思维、工作或协作方式等等,所有一切都会改变。

我参加的队伍由 8 名专业人士组成,出乎我意料的是我们中有 6 个之前根本没有任何采用敏捷完成工作的经验。这样,我们在其中 2 名有经验的同伴指导下开始工作了。一开始,让人高兴的事情并不多,大部分的事情都让人感到沮丧。我们认识到,敏捷并不只是冲刺(Sprint)和没有文档 - 有不少细微之处你得花功夫学才行。

这里说明一下曾经发生过的事情:

开始的麻烦

  1. 思维转变

敏捷讲的全是当下的考量、当前的冲刺、当前的用户故事等。当一路走来突然有其他某个故事出现在面前的时候,我们并不会事先考虑事情将如何发展。过去在瀑布模型里,我们常常是首先考虑整个系统,HLD(高层设计)和 LLD(低层设计)是第一步,在继续前进之前,它们必须冻结。

相反,敏捷的内容完全是当前状态和不断改变,要是我们的需求未来会变化,我们的设计也将随之演变;但是我们对于超越当前冲刺的事情并不是特别关注。要接受这一事实得花点时间。

  1. 持续换档

敏捷是一个不断变化的环境。“响应变化”是其主导原则之一。为了响应,开发者必须跟市面上的技术保持同步,否则它将让你异常痛苦。

我们曾在项目中使用了一种搜索引擎库,但我们中只有一人对其有了解。由于这个缺陷,我们在估时、结对、站立式会议,以及其他日常实践里都遇到了问题。

我们面对的另一个问题是恰当地进行 TDD。从技术观点看,TDD 已经有了不少选择。你可以依赖不同的模拟和测试框架,这些往往都是你在瀑布模型里不使用的东西。要是你想采用 TDD,那么就必须具备对它们的丰富知识,否则整个过程就不会太顺利。

缓慢地冲刺

  1. 测试驱动开发说的是先写测试,然后由测试导出业务逻辑。这是最难适应的事情之一,因为它完全颠覆了你的观念。 在瀑布模型里,总是代码先完成,然后再进行些测试(通常都有,但并非总是有);但 TDD 则完全是红、绿和重构。这种方法要求我们用抽象术语进行思考,然后由它们演变出具体的事物。由于一开始难以适应,我们往往求助于先写出逻辑,然后确保存在覆盖它们的测试。我把这称为开发驱动测试(DDT) 方法。

DDT 并没有增加太多的意义。假如你知道你的代码将会很好地工作,那为何还要写个测试呢?只是要证明这段代码确实有效?应该不止这一点。的确是这样。例如,写测试可以让你的代码在耦合性方面表现更好,而且还能够为将来的代码变更提供一个巨大的安全网。

  1. 在敏捷里,以抽象术语进行思考是开发人员必须具备的技能。在敏捷中我们并不像瀑布模型那样进行预先设计,通过创建抽象和开发工作流,设计到了一定的时候自然就会现身。敏捷中的开发人员必须至少精通基本的设计模式,否则他们将产生一大堆垃圾代码,从中只能得出拙劣的设计。 TDD 在这里对我们大有帮助。它要求我们按抽象术语进行思考。此外,只要我们开始修改测试,我们就必须考虑进行重构,让我们的代码变得更好。DDT 也能帮助我们立即识别任何质量问题,这样它们就能及时地得到修复。这样,我们最终认识到必须抛弃“首先编代码,然后写测试”的套路,后来我们重新开始采用了 TDD 方法。

  2. 代码质量是团队的职责,团队成员将时不时的重构代码或者可能会重新编写,直到它符合预先制订的标准。我们不要把任何情绪跟我们的代码关联起来,应该准备不断地抛弃或重写它。遵循 Venkat Subramaniam 在集体所有制实践方面的建议:“每次执行检入代码操作时,我们都应该致力于改善代码的质量。”

  3. 在瀑布模型里,需求是要签字的,有点像血誓,然后你再继续向前移动。但在敏捷里,需求与解决方案同步演变。这帮助我们在前进的过程中让事情变得越来越清晰,但这也导致系统需要不时的重新设计,在最初的冲刺(1-4)里,这种情况经常会发生。此外,Backlog 也能在冲刺的中间改变,因此,团队应该根据这些变化进行调整,因为在每个冲刺结束时交付可工作的软件是敏捷的座右铭。

  4. 结对一开始让人觉得是浪费时间和精力。两人一起在同一故事上进行工作就像是各浪费了一半的时间和精力。而且,多人完成同一故事的不同任务似乎是导致速度下降的原因。 但是,敏捷中的团队钟情于这种合作做事的方式,不喜欢相同项目组或房间里的人单枪匹马地干活。当团队一起工作时,他们会竭尽所能地把事情向前推进,结果你有极大的可能性是以一致的方式完成事情,而不是最终在多个战线失利。

  5. 在采用 TDD 时,结对的效果最好。Driver 和 Navigator 一起努力开发更好的系统。但如果你是按照 DDT 的方式进行结对编程, 那它就不是最佳的前进之路。在这种情况下,两个合作者都不会知道该如何前进,例如系统设计应该像什么样子,这样你将得到很多噪音,产生最终必须重写的一堆源代码文件。 遵循 TDD 是最佳的方式,但要是你还没有适应它,你仍然可以结对:利用一块玻璃(白)板,首先画出某个设计流程图,然后其中一个合作者可以编写代码,而另一个则可以编写测试用例。

  6. 在演示时交付可工作的软件就像是冲刺的“石蕊测试”。但是,要是软件不是可发布的,你会不会仅仅因为软件可以构建、可工作,而认为一个冲刺就成功了呢? 当个别故事全部完工而某些没有,这样的冲刺算不算成功呢?那假如冲刺的全部故事基本完成但还有些烦人的小问题呢?

团队应该关注让整个故事完工,所有问题得到解决,并且满足完工标准;而不是慌慌张张地盯着 Backlog 马虎了事。一次实施蹩脚的冲刺没有任何意义,除了在继续前进之前必须将已完成的事情返工。时间常常是一个约束条件,因此根据故事的相对重要程度,团队应该找出一种对他们提议的解决方案更具质量意义的实施方法。位于 Backlog 顶端的故事必须尽量以最好的方式开发解决,随着我们逐渐移动到 Backlog 的底部,对解决方案的质量可能会有些妥协,但并不是对完工标准而言。对于故事的实现,更好的方式是宁缺勿滥。

  1. 站立式会议是铁律。它们意味着成为一个共享平台,不只是你个人的有机会告诉其他人你做过什么和接下来要做什么。人们应该试图去倾听周遭发生的事情,而不只是检查自己的检查表看完成了哪些活动。 庄严的站立式会议也必须控制在一定时间之内。我们常常会抑制不住开始就某个问题进行讨论的诱惑,但那是必须要避免的。

  2. 敏捷团队相当小,在这样一个环境里,人们经常会因为他们在站立式会议上的言论而被他人评判。那么,你就应该说我们在彼此进行脑力激荡或者我昨天什么也没做,再或者是我们重构了代码,而现在我搞不清楚怎么回事了之类的事情吗?这些都只会给新人造成一种尴尬的局面。

  3. 计划会议肯定是费脑子和让人精疲力竭的活儿。坐在椅子里 4 个钟头确定故事点数就像是在玩轮盘赌。这些数字将决定包含在冲刺里的内容,但是怎样在你根本没有经验的时候决定数字呢?你一定会估计错误。 但这些数字注定就是可能会出错的大致数字,这并不意味着你纯粹是靠运气来开始玩轮盘赌。这些数字在未来的几个冲刺之后将给予你某种指示,告诉你能够完成的工作量。

  4. 分配故事点数是一个复杂的任务,应该按阶段完成。团队内部应该首先分析故事,并与产品负责人进行讨论以清晰地了解需求。在得到清晰的视图之后,就要进行广泛的技术讨论,考虑可以实现的最佳可能解决方案。这步要是完成不好,将导致在故事应该如何实现方面模棱两可,进而导致有缺陷的估计。假设,如果某个故事接触到了一个新的未探索领域,那么它应该会相当复杂,即便它是一个简单的任务。即使在已知领域,技术解决方案的不同也会导致故事相当复杂。 简单干脆的故事最容易被估算,即清楚地知道需求是什么,再加上点应该如何实现的细节。产品负责人无法提供这么干脆的故事。它们只能通过跟团队一起讨论得出来。因此,团队必须花点时间来为下一个冲刺进行调整。

  5. 回顾就像是在投票时间被赐予的演讲。我们应该已经完成这个或那个,在下一个冲刺里我们可以完成这个或那个,但是要是这个冲刺里没有接受某 些活儿,什么都不会发生。人们可以表达出对于不同方面的满意与否,但是团队应该着眼于从回顾的观点里得到某些具体任务,否则境况将永远保持下去。

在扎进敏捷之前,你可以做点准备工作:

  1. 熟悉市面上的技术,尤其是像 JUnit、Fitnesse、EasyMock 这样的测试工具。此外,人们应该不断地为更好的解决方案而奋斗,因此出去找找改进流程的新工具和新方法,寻找解决反复出现的问题的新框架或新设计思想和模式。

  2. Venkat Subramaniam 和 Andy Hunt 的“高效程序员的 45 个习惯:敏捷开发修炼之道”是每位涉足敏捷的开发者的必读书籍。

  3. 读读 Robert C Martin 在 objectmentor.com 上的“Craftsman series”和“Clean Code” 。一开始,你可以不用急着去读它们,但在你碰到一堆麻烦的时候,你就会知道什么时候该去读了。

  4. 在站立式会议 / 计划 / 讨论,人们评估你建议的时候中保持一颗开放的心。说出你的观点,或者必要的时候要求帮助,你是这个项目的受益人。

  5. 测试不仅仅是为了代码覆盖率或质量度量。它们还提供了某种类型的持续保持更新的文档。人们可以先看看测试代码,然后就知道该如何使用这段代码了。

  6. 在项目开始就自动化构建过程的所有事情。如果像 Checkstyle 这样的小事都遗漏了,那么它的结果跟其他模型里的一样,说得多做得少。当你意识到这一点,求助于某种补救手段时,时间往往都太晚了。

学会说 A 到 Z,然后再让你忘记,重新学 Z 到 A 往往不会太容易。这会带来些痛苦,但完成转变之后,你就会知道这样做是值得的。

话就说这么多,同志们,上路吧!!:)

查看英文原文: Confessions of A New Agile Developer


给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家加入到 InfoQ 中文站用户讨论组中与我们的编辑和其他读者朋友交流。

2010 年 11 月 12 日 00:005377
用户头像

发布了 255 篇内容, 共 45.4 次阅读, 收获喜欢 1 次。

关注

评论

发布
暂无评论
发现更多内容

区块链系列教程之:比特币中的网络和区块链

程序那些事

比特币 区块链 网络 p2p

锦囊篇|一文摸懂EventBus

ClericYi

锦囊篇|一文摸懂OkHttp

ClericYi

springboot整合Quartz实现定时任务(api使用篇)

北漂码农有话说

极客时间架构师训练营 - week3 - 作业 2

jjn0703

极客大学架构师训练营

架构师训练营第三周学习总结

CATTY

重学 Java 设计模式:实战命令模式「模拟高档餐厅八大菜系,小二点单厨师烹饪场景」

小傅哥

设计模式 小傅哥 重构 代码优化 命令模式

关于多线程,你必须知道的那些玩意儿

ClericYi

Prometheus 2.19.0 新特性

耳东

Prometheus

第三周课后作业

iHai

极客大学架构师训练营

架构师训练营 -week3- 作业

晓-Michelle

极客大学架构师训练营

游戏夜读 | 《FPS关卡设计》

game1night

架构师训练营 - 第三周命题作业

牛牛

极客大学架构师训练营 命题作业

618 我们狂欢的是什么?

Neco.W

拼多多 电商 京东 活动专区

极客时间 - 架构师培训 -3 期作业

Damon

week3.学习总结

个人练习生niki

还有比二分查找更快的算法,面向接口编程Protocol,John 易筋 ARTS 打卡 Week 05

John(易筋)

swift ARTS 打卡计划 二分查找 binary search protocol

再谈云原生:我的看法

lidaobing

云原生 k8s 中间件

关于JVM,你必须知道的那些玩意儿

ClericYi

锦囊篇|一文摸懂LeakCanary

ClericYi

我们是如何做go语言系统测试覆盖率收集的?

大卡尔

go 测试覆盖率 精准测试

第三周学习总结

iHai

极客大学架构师训练营

学习总结 - 第3周

饶军

Redis系列(二): 连集合底层实现原理都不知道,你敢说Redis用的很溜?

z小赵

Java redis 高并发 高并发系统设计

锦囊篇|一文摸懂ButterKnife

ClericYi

设计模式的十八般武艺

ClericYi

ARTS-week-4

youngitachi

ARTS 打卡计划 arts

ARTS-03 -- ARTS-04

NIMO

ARTS 打卡计划 ARTS活动

架构师训练营 - 学习笔记 - 第三周

心在飞

极客大学架构师训练营

每周学习总结 - 架构师培训 3 期

Damon

week3.课后作业

个人练习生niki

单例模式 组合模式

InfoQ 极客传媒开发者生态共创计划线上发布会

InfoQ 极客传媒开发者生态共创计划线上发布会

敏捷初哥忏悔录-InfoQ