在传统的瀑布流程中,我们往往是期望通过前期细致入微的工作来确保一个阶段的工作被高质量完成之后才移交到下一阶段。后来我们慢慢从失败的经验中学习到,这种方法在变化的需求环境下实在是太过脆弱,不仅不能如愿保证质量,而且会造成更大的浪费,交付周期也不能满足要求。于是我们引入了迭代式开发方法,一个需求的分析、开发、测试、验收成了一个小粒度地更连续的过程,在这个小的交付循环中,看板帮助我们以更细节的粒度来管理一个任务每个阶段的工作质量。

  通常我们是这么做的。当我们把一张故事卡从“待开发”移动到“开发中”时,这张卡片必须是已经分析完成的。也是说,当开发人员准备真正开始开发这张故事卡之前,我们的需求分析师们必须保证这张卡片所包含的所有内容和细节已经被分析完成,不再有模棱两可的细节,不再留给开发人员过多的自我发挥和想象空间,而且这些细节必须和客户确认过,而不只是团队自己“设计”的结果。

  这一道关看似很寻常,实际上很多项目会在这里出问题。很多时候开发人员开始开发的时候,需求还没有分析完成,很多细节尚须澄清确认,实现上的技术风险还没有被完全排除。也有的分析师善于给开发人员留有大量自我发挥空间,需求过于言简意赅。开发人员开始开发这样的需求时,要么做不下去,要么按照自己的理解做下去。做完了之后分析师一看发现不对,和我想的不一样,于是开发人员返工。糟糕的情形莫过于后被客户发现说,这不是我当初想要的东西。

  由此可见,确保开发人员挪卡的时候,这张待开发的用户故事已经被真正分析完成,是我们准确实现用户需求的第一步。通过规定这一挪卡的前提,同时辅以用户故事的澄清(由分析师向开发人员澄清)或者反向澄清(由开发人员向分析师讲述自己的理解),可以很大程度上将返工减少到低。

  还有一种浪费发生在测试过程中。测试人员经常会发现,处于“待测试”状态中的一些故事卡,在测试的时候主要的流程都走不通,根本无法进一步展开测试,于是乎不得不将故事卡

  打回到开发人员手中。而往往这个时候开发人员已经工作在另一个用户故事上了。要么他停下手中的任务解决测试的问题,要么让测试人员等到这些问题修复过后再测。无论哪种都是不好的选择。

  这种问题的一个主要原因是因为开发人员声称他已经“开发完成”,将故事卡从“开发中”挪到“待测试”时,实际上自己并没有对这部分功能进行测试。或者是因为疏忽,或者是因为懒惰,或者是因为过于自信。通过在这个状态转换阶段引入用户故事初验,让分析师在挪卡之前先到开发人员机器上看看是否该故事卡包含的功能被实现了,可以很大程度上提升效率,减少浪费。若分析师在初验过程中发现了问题,那么开发人员马上能以小的成本进行修复,而不用等到之后测试人员发现时再来修复。而且,分析师初验也提供了一个判断实现是否良好的反馈点,这是我们能够看到一个需求是否被实现并能够真正工作的早的时间点。

  2.2 如何避免多任务并行

  多任务之间的频繁切换是一个常见的问题。表现在团队里的成员,特别是开发人员,会在不同的任务间切换。像前面的故事中提到的,可能这一刻还在实现某一个需求,而下一刻马上会被叫走去修复某一个遗留版本的缺陷。又或者该人手头被分配了多个任务,每个任务都在进行中,而没有一个处于完成状态。任务切换是导致效率降低的一个重要原因,不同任务间的上下文的切换会导致频繁地将任务当前状态在头脑中“压栈”和“出栈”,这些操作会耗费时间。如果完成一个任务需要一个人时间,那么两天内这个人可以完成两个任务,但是如果他在第同时开始并行工作在这两个任务上,那么完成这两个任务会需要大于两天的时间。

  大家可能已经注意到了,在前面的看板图中,处于“开发中”的所有任务卡片上都有一个小纸条,上面标记着正在这张卡片上工作的人的名字。如果说有两个人结对在一个卡片上工作,那么这张卡片上应该有两个名字。这一小小的实践可以帮助我们随时发现团队内某一时刻,是否每个人只工作在一个任务上。

 如果这一简单的规则能够严格被遵循,那么当我们看到一个人的名字出现在多张卡片上的时候,我们知道这个人此刻可能忙着在多个任务之间切换,而每一个任务都将不会在估计的时间点内完成。如果我们看到有人的名字没有出现在任何卡片上,那么他目前大概处于休息状态。团队内的每个人的名字都应该对应在一个小纸条上,如果你此刻工作在某个任务上,那么将自己的名字贴到相应卡片上,如果此刻没有工作在该任务上,将自己的名字移去。

  我们在领取“待开发”状态栏中的卡片时,保证每次每人只领一张卡片,不要多领,完成了这张卡片之后,再回来领下一张。当一张卡片被认领之后,我们会对这张卡片进行跟踪,在站会上谈论它的完成情况,谈论实现过程中碰到的问题。当它的进度和估计的可能偏差较大时,我们能够及时而不是在后一刻察觉到,提供需要的帮助,确保它能够顺利完成。这样一种方式让我们能够将注意力集中到小粒度的需求(例如用户故事)上,更多地关注这些用户故事的流动速度。而当每个小的用户故事能够顺畅地流动起来时,整个项目的交付也得到了保障。

  当然这一实践并不能自动保证团队内不再出现多任务并发、拖延、或者做和任务无关的其他事情等问题。可能有些人在做一个用户故事的过程中,突然中断去做了一些其他事情,但是

  却没有及时在状态墙上更新自己的状态。重要的是团队要有实现交付目标的共同愿景,能够透明地暴露问题,并且善于利用状态墙来发现和改进自身的问题。对于不成熟的团队,这可能需要一个转变的周期。

  如果一个团队的职责共享较好,代码被所有人集体拥有,每个人都被鼓励熟悉和工作在代码的不同部分,那么在这样的团队内便不太会出现把一大块任务事先明确给某一个人的情况。相反,所有人的工作事先不具体确定,大家会更容易形成某一时刻只领取一张卡片的情况,避免同时工作在多个任务上。实际上,状态墙的使用也可以帮助团队走向职责共享之路,只需要在大家领取任务的时候有意地给人们分配一些之前没做过的内容,同时安排好有经验的人与其结对工作,一段时间之后,团队内的人便会逐渐体会到和之前只是专注在一个模块内不同的工作方式。

  2.3 如何减少半成品库存,缩短交付周期

  一个需求的交付周期(leadtime)是从它被识别到终交付给用户手中所耗费的时间。交付周期越短,意味着客户从提出想法到能够在软件中实际使用到这个点子的时间越短。从客户的角度来看,更短的交付周期意味着自己的软件能够对市场变化的更快地响应,因而获得更强的竞争力,同时也意味着能够更快地验证自己的想法。

  任务管理的粒度太大会直接导致交付周期变长。极端的情况是将属于某一模块的任务在一开始全部分给负责这个模块的人,所有这个模块相关的修改都由他来实现。在一个按模块划分职责,每个人只负责自己具体模块的团队里,通常这个模块的负责人会实现这个模块的所有修改。不然,是将一个可能需要做2周到一个月的任务分给某个人。或者更好一点的情况是,单个任务本身不大,但是会将相关联的任务成批地分配给某个人。如果你的团队内也是采用大篇的“规格说明书”等word文档来组织需求的,那么要小心,这种问题很可能在团队内已经存在。整个团队没有小粒度频繁交付的概念,习惯了大批量长时间地交付方式。由于批量大,所以估计常常不准,而且时间跨度长,中间也会有更多地干扰因素出现,这些都导致任务不能在开始承诺的时间点交付。开发周期长同样导致测试活动的滞后,极端地滞后演变为所有开发工作完成之后才能进行测试,这是我们熟悉的瀑布模式。终的影响是需求的交付周期会很长。