本文发表于敏捷开发杂志的 2006 秋季版。该杂志是敏捷联盟的信息风向标,作者们从中与读者分享敏捷项目中的成功与挑战,解释各种各样的方法和工具,并介绍最新的研究成果。该杂志每个季度将其以 PDF 格式分发给敏捷联盟的成员,杂志编辑提供了这篇由 Dafydd Rees 撰写的文章。 ——编者语
没有什么简单的步骤可以确保向敏捷的平滑过渡。成功应用敏捷方法论要求在行为和形式上的真正改变。 ——Dafydd Rees
关于敏捷方法论的文章已经很多了。其中,相当一部分文章讲述了敏捷方法技术方面的问题,比如测试驱动开发和持续集成。同样,还有相当一部分文章讨论了敏捷 方法论的应用问题,例如发布计划,跟踪生产率,如何使用度量数据对过程“调优”,甚至让公司里的业务人员确信需要采纳一种特别的方法。读过这些有关敏捷方 法的文章后,很容易让人产生一种感觉,即通过购买一套工具并遵从一系列看上去很简单的实践,就算采纳了像极限编程和 Scrum 这样的敏捷方法。然而,现实 世界的经验表明,成功地采纳敏捷要比那复杂得多。它涉及到如何培养一些正确的做事态度来建立信任,鼓励交流与协作,最终让人们更加适应,并产生高效。
敏捷方法常常被描述为以人为中心,而不是强调技术,并有充分的理由来说明这一点。然而,虽然敏捷宣言强 调了“个体和交互胜于过程和工具”的重要性,但它并没有清晰地阐明如何处理这个重要的社会性维度。在强调技术的业务中,这些都太简单,无法概观个人态度在 项目团队中的强大影响力。要想知道哪种态度可以促进(或阻挠)敏捷的采纳,我们要问一个问题:“在成功的开发者和管理者之中,我们能发现那些与众不同的行 为吗?”,更重要的问题是 “这些行为是由什么态度驱动的呢?”
成长中的敏捷开发者
很多开发者习惯于独立工作,花费大部分的时间来阅读规范,并完成设计和编码。在前敏捷环境(pre-agile environment)中,一些开发者甚至戴耳机听音乐,不听来自办公室的“噪音”。采纳极限编程的开发者发现其自身已经融入到更加社会化的环境了,在 这种环境下,成功依赖于与同伴和客户更紧密的协作。另外,经典的前敏捷开发是个体独自“拥有”那些设计和编码。在敏捷环境下,工作任务由团队共同决定: 没有谁能独自拥有某段代码。这种态度的调整可能特别具有挑战性。
刚接触敏捷开发的人可能习惯于在那种将自身划分成子系统再进行开发的项目。他们习惯于依据各子系统之间互联的高层次规范,独自负责某个子系统的设计。刚接 触集体代码所有制的开发者很容易被他们不得不掌握的代码的数量吓倒。与此同时,很少的技术文档(甚至没有技术文档)和快速变化的代码基线(包括那些熟悉的 类名和方法名都有可能在短时间内发生变化)很可能加剧这种情况。但是,敏捷方法论(特别是极限编程)要求编程人员有很强的编码能力。通过对缺乏经验和富有 经验的敏捷开发人员的观察,很容易就可以看出不仅仅是技能问题,态度也是非常关键的。
传统团队 敏捷团队 子系统所有权 集体代码所有权 一次性设计 增量开发 全面且完整地理解子系统 探索,发现 大量的事先设计,“结果管理” “技术原型”,试验 全面文档化 自动化测试 通过分析整个设计保证质量 通过测试驱动开发保证质量 需要一个全面的分析 探索并限定相关信息
(例如,代码覆盖,小的任务,优先级划分等等)
个人设计决策 形成且尊重团队的一致意见 把规模大小或复杂性作为成果 把规模大小或复杂性看作负担,尽可能减小 预先决定,尽量不改变设计 设计无止境,易变性,把变化作为学习的机会
表1:传统团队与敏捷团队的对比
表一在代码级别上列出了一些传统团队与敏捷团队的不同。富有经验的敏捷开发者有不同的编码方法。他们倾向于灵活编码,而不是等到整个设计都很完善了再进行 开发。另外,他们还倾向于把编码视为学习和探索的机会。例如,遇到一个问题时,他们总是通过编写一个小的概念验证模型或“技术原型(spike solution)”使问题具体化,而不是构建一个复杂的模型或者通过自然语言描述来说明各种行为。同样,敏捷开发者更愿意去阅读第三方的代码。有时候, 他们想做一些力所能及的改进;有时候他们这么做只是为了学习一种新的设计方法。最后,通过尽可能地让类、方法以及与潜在的方法调用链等相互独立,以便仅了 解局部代码就足够了,这样就不用去花很多时间去研究整个子系统或应用。所有这些差异能更好地使开发者发现并处理编码中出现的问题,而不是仅仅使用高超的编 码技能完成任务而已。
拿结对编程为例。对于采纳敏捷方法论(尤其是极限编程)的团队来说,结对编程是最有争议的几个问题之一,因为它需要两个开发人员共同完成同一段代码。虽然 一个开发者可能具有杰出的设计能力并精通开发平台,但作为一个高效的XP 开发者,他还必须能够沟通思想,协作进行测试,提供可能的实现方案,并在某个实现 策略上达成共识。很多开发者不愿意进行结对编程,并不是因为他们不会编码,而是因为他们不熟悉结对编程。有个开发者在他的blog 中写道:“结对编程会使 他们暴露他们真正的知识和技能水平”。独立编程时,别人只会看到编码结果。而结对编程时,不顺利的开始和早期犯的错误都会被别人看到。这时肯定会有一种压 迫感,甚至对高水平的开发者也是一样,要花上一段时间才能习惯。值得牢记的是:当你了解了其它团队成员,并且熟悉每个参与者的个性之后,结对编程就会变得 容易起来。
大多数成功的极限编程者对使用各种语言编程、学习新的设计方法都相当感兴趣,特别是阅读已存在的代码。这些成功的开发者愿意通过尝试做一些小的练习来“实 践”编码。他们可能会通过编写一些小工具或参与开源项目进行实验。在这里,着重强调“实践”是非常重要的。好的敏捷开发者常常通做一些事情来掌握知识和技 术,而不仅仅通过阅读了解它。
“极限编程是共产主义……”这就是某个开发者对结对编程的牵强解释。他提到,在XP 中的编码使大家分享了的各自的经验,他嘲笑“集体代码所有制”,并对所 有开发人员可及接触所有领域的工作以便能够编写任意部分的代码这一事实嗤之以鼻。我与这个开发者聊过一段时间以后,才明白他的想法实际上是为了与他人竞争 以保住“饭碗”。他担心同一团队中以及不同团队间的竞争问题。与别人一起工作意味着允许别人看到他是怎样解决问题的,用了什么工具,这就使别人有机会学到 他的诀窍。他对结对编程的反感表明,在敏捷团队中需要解决个人英雄式开发和“饭碗”问题。结对编程很自然地使开发者向同事敞开胸怀,分享领域知识,并时刻 准备把你的方法与大家分享。
一个极度自信的开发者也可能会抛开结对编程这一方式。有时面对生产速率下降而一个成员独立工作可以使其提高的情况下会发生这样的事。另外,当一对开发者中 的某个人能力不济,而另一个人就会把“结对”变成“个人秀”。 还有一些时候,其中的一个开发者可能急不可耐地想完成任务,因为一些个人原因驱使他尽快完成用户故事,可能最显而易见的原因就是“野心”:试图通过展示技 术能力成为团队领导者,或得到其它晋升机会。这样的态度很容易使结对褪变成一个“得分比赛”,比赛的目标就是看谁能赢,而不是设法完成有意义的工作。
过少的发言权也可能是成为一个问题。一个开发者很少主动关心他的结对任务的话,很可能他就会被他的伙伴所领导。在这种情况下,这个开发者实际上是放弃了很多在设计和代码质量上的责任。
塑造敏捷教练
至此,我们仅讨论了在开发者中发生的常见实践问题。然而,创建和维护一个具有敏捷态度的开发团队也是教练和其他领导者最重要的责任。这些领导者必须为他们的团队建立一套好的样例并成为真正的教练,而不是成为只有“教练”头衔的团队成员。
最有效的领导技能之一就是建立一整套好的样例。开发团队会建立一整套规则,比如所有的产品代码要结对编写,所有的产品代码都要先写测试等等。只有团队成员 坚信这些规则是非常重要的,这些规则才会起作用。然而,“说了不做”真的是太容易了。例如,团队领导者向团队成员宣布:“构建失败了,我们现在最重要的任 务就是修复它。”刚听到时一定会信以为真,可是接下来的话却不是那么回事了,“我第一个发现了这个问题,原本应该由我来修复它,可是我太忙了。”他的行动 使其对这件事的重要性大打折扣。别人会认为,构建可能是现在最重要的事,也可能不是。作为一个团队领导者,让别人看到他正在与一个开发者一起修复这个构建 是很平常的事情。这么做可以向团队成员进一步表明,构建是一个非常重要的事。
好的教练并不仅仅是知道如何教开发人员技巧,还要鼓励开发人员务实思考,并高效协作。这有点与Ken Schwaber 所描述的ScrumMaster 的角色相似,即该角色对鼓励团队协作负有责任。当教练拒绝解释而直接用自己的知识来解决问题或者以命令的口气来领导团队时,这就是一个不太好的信号。
我想,最好从外面请一个人来作为“教练”帮助团队,而不应该是团队的固定成员。如果教练是团队中的一个固定成员,那么会存在利益冲突:有时他要帮团队成员,以便提高团队能力和效率;而有时他要客观地评估团队,在团队成员之间做一些比较。就象Kent Beck 在他的《 Extreme Programming Explained 》一书中所提到的,一个教练应该有一个目标,即帮助团队成长,最终达到不再需要教练。一个好的教练需要一定的自信和情绪控制力,也需要技术能力和经验。
铲除潜在的问题
有几个潜在的因素会对团队态度产生负面影响。一些团队成员很担心:他们的团队领导做改革只是为了进一步达到个人目标,而不是为了使团队做得更好。另一部分 成员不愿意面对变化的原因是怯于表达。另外一个特别麻烦的问题就是:谁不喜欢自己得到夸奖,并可以批评别人呢?可是我们真正需要的是虚心地接受批评和学 习。
在软件业,很多创新可以得到个人奖励。写东西和在会议上讲演显然都会提升个人形象。技术领导者、教练或处于同样角色的人就处于一种可以引入变化的位置上。 我们应当意识到,尽管我们鼓励创新,但变化也有可能带有破坏性或给已经高效工作的团队更大的压力。因此,和团队一起进行回顾找到解决方案要比由领导宣布某 种改进策略要好得多。
“激励整个团队拥抱变化要比使用权力来执行对他们自己及业务有利的某些变化好的多”。对于领导者来说,能认识到这一点是非常重要的。正如一个开发人员抱怨 说:“这么做只能使我们更伤心。他们只想通过会议来使他们看起来更有权力。”他认为在他的团队中,只是为了使团队中一两个权威人士显得更专业就将某种革新 强加在团队之上,甚至不顾这会使软件交付的每日任务更难完成。所以另一个关键之处就是要认识到每个人都需要稳定性和安全感,而过多的变化会使其很快动摇。
然而有时很明显的是,人们已经根深蒂固地反对那种尚未发现的变化。不管已经有多少人的担忧被巧妙地说了出来,还是会有更多的担忧不断涌现,这是经常发生的 事情。很可能那些提出个人担忧的人就有某种个人或动机问题需要改进,这是好事,但说出来以后并不一定会感到舒服一些。例如,很多人可能会对极限编程提出一 些技术和业务方面的异议。很少有人会坦言真正困扰他们的到底是什么。例如,你不可能听到:“使用 XP 意味着固定的工作时间,所以我不能到学校接我的女 儿。”
当团队成员发现他们可能要使用某种新的技术平台来构建一些产品时,同样的事情也会发生。一些开发人员强烈反对这样做,他们的理由就是“我们需要多考虑一些 技术问题,例如可扩展性、学习和维护成本、工具的质量等等”。几个月以后,我们就会发现,真正的原因是很多开发人员不想花时间去研究被提及的新平台,因为 他们感到学习新技术平台会证明他们的个人学习能力不行。从专业角度来看,尽管职业发展、就业能力和工作与生活的平衡都都是很正常的问题,但对于个体来说, 还是很难消除这种担心。
在培养敏捷团队中的最后一个潜在因素就是需要一点谦虚的品德。在敏捷团队中,谦虚有很多好处。其一就是它减少那种反生产力的“得分式 (point scoring)”竞争的可能性。这正是与 XP 中的“做最简单的事”相吻合的心态,正象 Steve McConnell 在《Code Complete》中所指出的,它鼓励开发人员写可读性更高的代码。当你想批评别人,尤其是当他正努力采用敏捷方法的时候,你就该学习如何保持谦虚的心态 了。虽然别人有缺点,但当你看到了一个缺点并自问“我曾经犯过同样的错误吗”时,这才是重要的。你可能无法改正别人的缺点,但你肯定可以从中学到东西。
结论
在敏捷团队中培养高效的态度和工作方式是一个复杂而关键的活动。很多试图进行敏捷项目的人把焦点放在业务上。尽管业务很重要,但是一定要记住:项目干系人 都是人。他们也有他们的个人需求和关心的事情。一个成功的自组织的项目团队需要每一个参与者都能真诚地来推动各方面的改进。敏捷不是被“统治”出来的,但 是,假如给予那些具有能动性的团队成员进行自我组织的自由,那么敏捷是能培养出来的。
关于作者
Dafydd 是专注于敏捷方法和面向对象开发的软件开发人员。他希望与大家共同讨论。请将反馈信息放在 www.dafydd.net/feedback.php 上。
查看英文原文: Cultivating Agile Attitudes
评论