每当我听到其他软件负责人抱怨他们的“类瀑布”开发流程,我总问他们为什么不尝试些更敏捷的方法呢。而最常见的回答就是他们不知道如何开始。事实上,如果一本书通篇都在以敏捷开发为主题,也不会使敏捷更容易。向项目管理团队解释你想放弃已知的一切,然后去试那些完全不一样的东西确实需要一整本来描述,而这将需要些功夫来销售。这类改变往往让管理团队畏惧。
可事实上,敏捷开发是非常简单,而且是可高度定制化的。你可以在开发流程的任意地方开始实行敏捷原则,并做出修改直到它完美地适合你的团队。之所以相信这点,是因为我亲眼见证过。我工作的国防工业是一个你写任意一行代码,都需要等到足够的纸质文档被创建为止,而这些纸张能足足消耗掉森林中一堆动物的家园。但是,即是在这种看起来“非敏捷”的文化中,我们也已成功地应用了敏捷原则和实践。通过几个版本的学习,我的团队现在遵循一个定制的,非常有效并适合我们“国防工业”的环境的敏捷流程。本篇文章讲述了我们的敏捷软件开发流程和我们如何从传统的瀑布开发流程迁移到敏捷开发中的故事。
流程
改变 1:采用迭代开发
敏捷开发最根本的部分就是持续集成和测试。敏捷流程致力于快速和频繁发布代码,以让终端用户和利益相关者使用功能(尽管不完善)可用的软件同时,提出建议以适时调整。尽早发布可以工作的软件就好比购买了保险来对抗失败的可能性。如果你想交付客户喜欢并且最终会使用的软件,那就将其分块并及早和频繁地展示给客户。否则你最后交付给客户的可能就是客户去年某个时候他们觉得他们当时想要的软件。
采用迭代的开发风格,对我们是一个巨大的变化,尤其是对一个原来需要先把所有事情都写出来的流程来说。我们的传统“瀑布”流程要求系统工程师给出需求,然后将其细化为软件需求,最后移交给开发团队(被放置在架子上并忽略不计)。只有在软件需求最终确定并被批准后,开发团队才能开始编码。使对持续集成的过渡成为可能的是使团队认识到“足够好”其实比“完美”要更好。我的意思是,系统团队获得许可可以在流程开始的时候就给软件开发团队一个原始的系统部件。然后软件团队可允许使用这些原始部件开始实现原型。这些早期的实现,反过来可以发现缺陷,从而引导出新的和更好的系统部件。团队不需要从开始时就有“完美”的部件。他们只需一个简易的起点以及时间来做更多细小的改变。
我们敏捷的第一步开始于将一个 1 年之久的瀑布式项目转换为数个 8 星期长的迭代。这些“迷你瀑布”帮我们解决了几个问题,并把经常被忘记的主要流程问题拖到聚光灯下 - 即整合的成本。每个发布仅有一次代码集成就是个噩梦,我们总是要花上比原计划更多的时间来处理。但是因为这个问题并不频繁,而且如此可怕,我们都假装它不存在直到下个版本计划。当转换到一个使我们每隔一个月都要经历这种痛苦的流程时,明显说明了我们有问题。我们通过每一个迭代来学习,进步,并且在集成时变得更有效率。在年底第六个迭代时,我们解决集成问题的效率以及团队无连接问题比第一次提高了两倍。
在接下来的几个版本中我们开始缩短迭代周期直到找到最适合我们的。现在我的团队采用两周作为一个迭代周期。每两周我们就交付可以工作的,经过测试的软件,并重新计划接下来两周的工作。在早期迭代中,软件和系统团队一起合作创建需求,原型和设计—一个团队的输出正好作为其他团队的输入。随着迭代的深入,每个团队都重定义他们的部件并收集终端用户和利益相关者的反馈。在晚一些的迭代里,原型变为对产品代码的缺陷修改和对相应的两周内要处理和集成的开发工作。总体来说,迭代开发的优点是让人吃惊的:
- 系统工程师最终定义什么是 _ 正确的 _ 系统(在国防工业中非常重要)
- 软件开发可以更早地开始,并且可以真正为系统部件做出贡献。
- 测试人员得以看到不断演变的功能,使他们获得更多的知识和自信来玩转系统并找出问题,而非简单测试需求。
- 集成总是痛苦的,但是集成只有两周工作量的代码是很容易管理的。另外频繁集成能让你学到导致痛苦的原因,然后在下一次迭代中修复它。
- 查找并修复在过去 2 周内代码中的缺陷比试图解决在几个月都没碰的代码中要容易得多。
- 集成使你与测试团队建立起更紧密的关系。开发人员和测试人员一起工作,而不是像对手一样。
- 当事情开始往错的方向发展时,我们可以尽早调整和校正。
改变 2:保持任务小型化
迭代开发主要的销售点就是它允许更频繁的修正,并能在缺陷变得不可收拾之前找到问题。这些概念也能在个人层面应用。比如如果迭代长达 8 周,一个开发者为这个 8 周任务一直工作,而他可能在整个 8 周内都向错误的方向行进,如果想改正这 8 周所造成的问题,大量的加班和其他员工的帮助是很难避免的。
在经历过多次这种问题后,我们采用了一条即“任何任务不可超过 40 小时”的规则。这意味着开发者必须把他们的工作粒度降低到 40 小时以内。这只是一个简单的流程改变,但是带来的益处却非常大。任何任务不可超过 40 小时意味着:
- 团队不会为每一个任务产生大量代码,这就使更高质量的代码检查成为可能 - 甚至能发现死锁和竞态条件。在一个时间检查 8 周的代码,换句话说,只能找到注释里的拼写错误。
- 管理者,同伴,代码检查者以及测试员等有更好的机会理解 40 小时或以内完成的工作。比如,一个 32 小时的任务“在地图上立体地显示同类出租物业”就比 400 小时,更为复杂的“地图特性”要容易讨论,检查和测试。
- 40 小时的开发即使方向错误也很容易改正。
改变 3:使用伙伴体制
结对编程是一个在“极限编程”中定义的新概念,两个程序员结成一对完成一切事情。该想法认为两个开发者共用一个键盘更容易在第一次时开发出正确的软件,并可节省软件开发生命周期的后端时间,虽然我从来没有看到过它在学术界之外获得应用,我也不知道哪个开发者愿意一周 5 天,一天 8 小时都和同事坐在一起,但这个概念还是非常有意思。
相对于结对编程,我的团队使用“伙伴体制”(对了,就像在幼儿园的实地考察)。伙伴体制严格上说不是结对编程。但我们借用了它的核心概念并针对我们团队的文化做了相应的改变,以保持它的优点。每一个程序员在日常工作时都有一个“伙伴”。在一个开发者开始一个任务之前(记住,在我们的流程里没有计划任务允许大于 40 小时的工作价值)他必须与他的“伙伴”会面,解释问题以及对该任务采用的方法。此过程只需要 5 分钟,却节省了很多时间。
伙伴体制也适用于架构和设计层面。在设计阶段,特性设计师要至少每隔一天就和他的伙伴会面讨论对他们设计主线的更改。通过这一流程变化,我们能在第一时间设计出正确的东西,并且显著减少在开发阶段发现严重的设计问题的可能性。
伙伴体制的优点包括:
- 你的“伙伴”处在一个做代码检查的更好位置因为他们理解你要创造“什么”以及“为什么”。
- 在尝试一个解决方案之前,通过对话来讨论它,往往会发现很多陷阱并能防止弯路。我已经记不清有多少次,在准备任务的前五分钟讨论后所得的结果是“哇,这个方法是错的。”
- 万一你赢了彩票或者退休了,你正好训练了一个替代者。
我们未来方向
一个软件流程会由于团队持续学习并发现什么能让工作更好而不断演进。我们的团队从把一个火炉管道瀑布流程迁移到使用紧密集成,具有适应性的敏捷中取得了很多进步。我们还在继续改进一些事情:
- 我们已经开始从传统的需求,那些“早”部件中迁移开。相应地,将那些高层次的概念,用例,用户故事,和系统线程带入中心舞台。但需求,这一无法避免的“邪恶东西”,仍将作为对政府的承包存在,但他们真的是一个可怕的开始点。
- 我们正在努力进一步完善我们的未完成任务栏和迭代规划流程,以改善我们估计的准确性。软件开发估计是一个很难掌握的技巧,但对预算和截至日期都是铁定的行业来说,是极端重要的。
- 频繁迭代使得开发和测试团队紧密耦合成一个团队,但是我们仍然想把系统工程师也加入到其中。
总结
这篇文章描述了国防工业领域的一个开发团队遵循的简单的敏捷流程。它也提供了关于如何从痛苦的瀑布流程迁移到更为敏捷的流程上的一些启示。运行敏捷并不需要记住无数书本内容,或一个背后印有“SCRUM 大师”标签的长袍。读书以及参加培训会给你新主意,但变成“敏捷”最重要的特性是愿意做出微小的变化和调整。简单来说,敏捷就是意味着当某些事情行不通时要有做出改变的能力。
关于作者
Jeff Plummer是通用动力公司 C4 系统小组的某一集成产品团队负责人,他负责指挥和管理团队中的系统,软件和测试工程师。大家可以通过 plummeronsoftware@gmail.com 和 Jeff 沟通,讨论问题。
查看英文原文: Agile in the Defense Industry
评论