写点什么

拿看板拯救你——我的“红”项目

  • 2012-12-04
  • 本文字数:6987 字

    阅读完需:约 23 分钟

这篇案例讲述了如何运用看板以及精益开发技术,拯救一个“红”项目。

背景

本文所讲的是一个做了将近一年左右的大型客户端用户开发项目。前前后后,开发团队基本维持在 10 到 15 名成员。

在项目开始的时候,团队采用传统的瀑布开发模式。代码开发阶段之前是需求分析阶段,需求分析通常要花上 2 到 3 个月而且还会延期。更甚的是在需求分析阶段,项目范围经常变动,往往超出之前客户与开发团队达成的共识。由于客户坚持需要把需求“确定下来”以及开发团队也必须得到客户对需求文档认同的“签署”,这个需求分析的周期花了将近 6 个月才结束,大致是 100% 的进度超时。

尽管事实是需求分析阶段已经超过了原定的计划时间,但项目结束的日期并没有因此更改以便符合现实状况。可想而知的结果就是,开发团队被迫在更少的时间内交付更多额外的功能。最终,在开发期限截至时没办法完成,而且由于测试也是草草收场,开发的验证并不充分。

此外,由于项目经理没法管理好客户,保护团队不被客户干扰,整个团队在一种“干扰驱动”的模式下运作。典型的模式是客户向项目经理叫嚣某个质量问题,然后她再把这个信息传达给团队。因此无论哪个危机出现,都无法及时修复。团队没有办法集中在一个问题上,在没有干扰的情况下完成工作。 当我空降到这个项目的时候,客户与开发团队的关系非常糟糕,客户拒绝支付。用户也不愿接受已开发的功能、可靠性及性能。项目已经超支几十万美元,计划进度也落后计划几个月。不论是客户还是开发团队,都没法承担这个项目失败的恶果,因此必须做点什么把局面扳回来。

掌控

当你面对这种情况的时候,首先要做的是千万不要惊慌。在这个案例中,客户非常激动并且对团队完全没有信心,客户与团队甚至还相互指责。士气很差并越来越差,原因只是管理层期望团队能够努力工作修复问题。

这个时候,你千万不能火上浇油,一错再错,一意孤行地继续着你的错误。 经验表明,对这类情况最佳的方式就是针对数据和事实,而不要带入个人情绪。很重要的是,我们要去挖掘事情起因的根本原因,这样才能发现纠正的方向。但并不需要让团队觉得他们现在所做的每件事情都是错误的,那样做只会让情况更糟。(译注:认同感同样重要,总能有一两件事情团队做得还不错。)

在这个例子中,主要的问题是产品质量很糟糕,已发现的缺陷数也支持这种说法。我们必须让产品成功地交付一些功能,使客户能够使用。而当务之急就是创建一种环境,让团队能够在某个时间段内只集中处理一个问题。

建立质量文化

如果我们反复强调的创建软件的重要性就在于能够正常地工作,并以此作为软件开发的前提,这似乎挺可笑的。但这一点反而是大多数软件项目不断受到挑战的主要方面之一。

在项目的早期,开发团队花了几个月的时间尝试把他们认为的客户想要的需求用文档的形式记录下来。恰恰相反,这导致了一种错误的感觉,让开发团队和客户以为这是他们最终要交付的软件。另外,只有那部分在需求分析阶段跟客户一起需求分析的团队成员才是分析员。直到分析员认为需求分析“完成”了,开发人员才能开始工作。

这引发了之后的一系列现象:

  • 开发人员不得不消化并说明客户的需求,形成作为原子单元的 200 到 300 页的文档。
  • 即使在双方“签署”需求文档后,客户还是不断地更改需求。这意味着开发人员的工作持续地被否定和更改。
  • 这导致了开发工期不得不延长到之前计划好的完工日期之后。
  • 测试必须等到所有的开发工作“完成”后的最后阶段才开始。由于原定的最后期限已过,测试被迫草草收场。
  • 质量不再是检验开发软件是否工作正确的度量,反到成为计算测试人员与开发人员之间用相同方式解释需求的频率的度量。

最终的结果是成百上千的缺陷从开发过程中偷偷潜逃并最终呈现在客户面前。诚然,缺陷是最差的浪费,因为他们是错误需求的已开发状态。这意味着客户花了钱购买开发的软件,然后他们(或团队)不得不消化掉使之正确运行的代价。

很明显,开发团队工作的方式并没有把质量放在首位,事实上,倒是把质量放在了末位。因为分析师、开发人员以及测试人员是被死板地放进项目里,各顾各做着独立的任务。他们从未像整合在一起的机器一样协同工作,他们也没能感受到协作的责任和系统质量的归属感。每当出现问题时,他们就互相指责。简而言之,他们没能创造并接受这样一种质量的文化。

我们决定着手控制质量的最重要的决策就是,要求开发人员在编写代码前首先完成所要开发的工作项的验收测试。这就是人们所说的验收测试驱动开发(Acceptance Test Driven Development 或简称 ATDD)。有了 ATDD,我们从字面上做到了把质量放在首位。

我们运用 ATDD 使之适合于这个项目的方法是,我们对每个 Backlog 里的工作项都要求有相关的验收测试。这样一来,那些没有被代码覆盖的需求就被有效地记录下来。这同样迫使测试人员和开发人员在编码开始之前就在同一起跑线上,有着相同的理解。开发人员的工作主要集中在让那些失败的验收测试通过。必须要澄清的是,测试是基于工作项级别进行开发的,而并不是同一时刻开发一批工作项。

这种方法彻底改变了凭空猜测的工作方式,开发的代码要么正确要么错误。测试要么通过要么失败。就这么简单,是与非,错与对。由于每个开发人员的注意力只集中在某个工作项上,与之前的工作模式去理解整个分析文档相比,一位开发人员在一段时间内所需要理解的验收测试数永远不会太多。 验收测试的状态过程有:

  • 失败。由于代码并没有实现功能并通过测试,测试立即失败了。
  • 已开发。让测试通过的代码已经编写。当开发人员实现代码时,他们确认了这个过程状态。
  • 通过。测试人员确认所开发的代码确实通过了测试。

仅仅使用 ATDD 方式就已经获得了转变产品质量的正向结果。

在使用 ATDD 的头 8 个星期里,我们把一个没有任何测试文档覆盖的文档转变成有着一全套测试以及测试历史记录文档的项目,从而保证了所开发的代码的整体质量。

根除浪费、遏制工作流

之前谈到过,开发团队刚开始使用的是瀑布模型的开发模式。然而事情最终变成一种特有(ad-hoc)的开发方法,一旦开发工作开始了,巨大的前端需求文档就因没有控制的变更而变得无效。用不了多久,需求关联的代码行就变得模糊,最终被删除。

分配工作任务是典型的推动式模式(自上而下分配下去),每一批的需求量很大。每次开发团队都会从需求分析团队那边接到一大批需求的文档。而每次测试团队不仅要读需求分析团队那边大量的需求文档,还必须看开发团队的大量代码库。在测试期间,如果发现了 某些缺陷,经理就会把这些缺陷推送给对应的开发人员。当缺陷被修复后,经理再把缺陷推送给相应的测试人员进行验证。

这种方法造成了严重的浪费。在需求分析阶段,大量的未实现需求堆积起来。在开发阶段,大量的未测代码越积越多。而直到最后的测试阶段,就会发现大量未实现或未正确实现的需求。

减少批次大小

成百上千的缺陷从开发过程中偷偷潜逃并最终呈现在客户面前。这种现象的起源可以追溯到团队工作的批次过于庞大。在一个时间段内,团队没有能力推动整个批次前进并维持批次的完整度。

尝试推动如此之大的产品的结果即是对某个任务而言前个团队势必成为后续团队的瓶颈。最终,这将成为不可能完成的任务,每个产品都沿着从测试到开发到分析的路线向后倒退消散。并且这样的流程周而复始。换句话说,将需求“确定”的所有努力都是浪费,每次发现了缺陷,团队不得不问自己“我们现在该做什么?”然而这样的提问本身就是浪费时间。

团队精神

我们必须打破这个恶性循环,把团队带到一个阶段,让他们能够真正地完成工作项并保持完工状态。这意味着我们需要改变团队结构,并且从根本上改变团队处理在制件到完成件的方法。事实上,就是改变他们对于工作状态——“完成”的定义。

团队成员经常对解决方案所有权无法达成共识,这种情况已经成为最主要的阻碍。我们首先做的是打散组织结构。分析人员,测试人员和开发人员现在都是开发团队的一份子。同样地,我们设定了期望值,将交付高质量产品的责任变成大家共同的义务,而不是像以前那样。只有测试人员才会对产品质量负责。

我们还特地把所有的团队成员都聚到一个大会议室里工作。这样做又一次强调了他们是同一个团队的事实。这也意味着他们能够面对面的交流,而非隔着办公桌相互发邮件。

从被动接受到主动请缨

我们要做的下一件事儿,就是解除项目经理分配任务的权力。这意味着,经理们没法再把工作硬塞给团队。之前讲过,团队在一种干扰驱动的模式下工作,经理能够临时把任务塞给团队成员,而导致他们无法将之前分配的任务完成。

为了使开发更有序并且彻底堵上缺陷潜逃的出口,我们借鉴看板引入了一种“自取式”系统。看板的方式迫使团队每次只能处理很小的批次。起初,这种方式很简单,因为所有需要完成的工作项都是缺陷。这些工作项通常都很小,这也迫使我们去定义“完成”。

通过这种方法,工作项(描述为卡片)自左向右经历看板的每个阶段(描述为列),从最初的等待状态到最终的确认接受状态。每当团队成员开始处理某个卡片时,他或她就会把卡片拖到下一列,代表他们开始这项工作了。团队成员必须在适当的地方运用他们的特殊技能,将卡片移动。直到工作项通过了所有的阶段,最终到达确认接受状态时,这个工作项才被认定为“完成”。做完等于确认接受。

每一列代表了需要被完成的工作以保证卡片前进。为了减少对已完成任务沟通协调的成本,我们增加了一列“准备阶段”,用来表明前次任务已完成,现在准备进行下一项任务。例如,当我们编写完验收测试后,下一个工作项是准备编写代码阶段。因此看板白板提供一种简单但行之有效的视觉机制,把流程转换成工作项的移动。这提供了检查每个在制品的状态的途径。

我们的看板白板上的每个列如下所示。注意每个工作项的第一个任务即是定义上述验收测试。

等待 编写测试 准备编写代码 准备阶段 准备接受 接受 确认接受很多时候,我们可以把看板白板画在墙上,并且用即时贴代表工作项。在我们的案例中,团队在地理上分布在不同地点,我期望我们能够经常地依靠可靠的度量数据来做出决定,保证流程变得更完美。我们选择了 VersionOne 作为我们敏捷项目管理的工具。

我们用过的最有用的工具之一就是累计流量图(cumulative flow chart)。这个图表让我们很清楚地看出工作项如何关联到确认接受的趋势。由于我们每周提供给客户一个版本,所以就按周的频率追踪工作项。我们也能够通过观察若干周合计的累计流程图来理解更广的趋势。

(点击放大)

上述图表显示了从我们接手以来8 周左右的工作项累计流量图。

上述图表的每个竖条代表了下列图表的每周累计视图。

(点击放大)

我们每天都要观察这些图表,以确保这周的工作项能够结束。我们发现这样的视觉机制比起团队之前用的电子表格形式的缺陷列表要有效得多。

消除瓶颈

我们同时引入了在制品(WIP)限制,用来控制工作项经历看板每个阶段的速率。我们观察发现,分析人员没法跟开发人员使用同样的速率完成验收测试。由于开发人员受到上游分析人员在制品的限制,无法进行新的开发任务,所以分析人员成为系统的瓶颈。这需要团队协同工作,一同找到均衡工作分配的方法。有时候开发人员不得不编写额外的验收测试并验证它们(不仅仅是涉及到他们工作的验收测试)。并且我们不得不增加分析人员和测试人员的数量。在某些情况下,我们调整在制品的限制,消除不必要的等待阶段。

最终,团队开始像一个真正的团队那样协同工作。他们被迫学会如何思考,如何让工作项通过看板系统。这极大地提升了团队士气,团队开始认识到作为一个团队对产品质量负责,而不是相互指责。在此之前他们仅仅被简单地放到这个项目,完成某些特殊技能的工作,然后回到资源池中。

分解部署计划

一旦我们解决了如何在看板系统中移动工作项的问题,就能把工作项放到backlog 里并做评估,保证团队在不受干扰的情况下取得下一个工作项。

之前,团队仅仅是被动地被告知应该开发哪个工作项,以及何时完工。除了之前所说的由干扰驱动任务模式所带来的问题之外,开发人员从不曾严肃地看待完工的最后期限。因为他们从不曾对工作项的评估负责。那些项目经理对客户给出的承诺没有任何实际意义,项目经理并不知道完成这个工作项应该花多少时间,他们只是对客户说他们爱听的话。这就导致了开发从来无法在最后期限内完工。最终,项目经理不仅在团队中颜面扫地,失信于人,在客户心中也是一样的。由于项目经理让大家觉得似乎每件事情都是紧急的,他或她不明白这恰好创造出另一种氛围——任何事情反倒都不重要。

在敏捷方法中,最核心的观念就是由实际做这个工作项的团队来评估工作量。然后,我们要做的是保证团队在工作中受到最少的干扰。

优先级排序

如果每件事都重要,那就没有一件事重要。要做到持续工作流的关键之一就在于找到类似看板系统一样的工作自取模式,让团队的每个人对下个要做的最重要的工作项有一个连贯的认识。如果每个人都能知道下个被取到白板上的工作项是什么,那么我们就不需要在协调成本上花太多功夫,帮助团队理解下一步做什么。

我们用来维护所有工作项的核心机制就是backlog。所谓backlog 就是所有由产品负责人和用户所确定的潜在工作项的已排序列表。用户故事(user story)和缺陷都是工作项的形式。用户和其他利益相关者都能够提出请求新增工作项,之后这些请求就进入backlog 列表。新增的工作项不会对正在进行的工作造成影响,相反,backlog 就成为存放新工作项请求的空间。新工作项表明团队与提出请求的申请者之间有过新增工作的沟通。

我们对backlog 里的所有工作项都做了优先级排序。因此backlog 里最上面的工作项就是团队下一步需要工作的最重要的事情。一旦产品负责人意识到工作项顺序的重要性,他们会自发地对backlog 中的排序起到关键作用,以保证顺序的合理性。需要顺便指出的是,对于不断变化的业务需求,工作项的优先顺序也会不断地调整。

之前,我讲到过我们做的第一件事就是废除团队经理分配任务的权力。现在,我们做了些调整,把项目经理的角色调整为和客户紧密工作的人,保证客户及时地对backlog 里的工作项进行排序。是的,我们强制项目经理去做这些,因为他们习惯于通知团队该干什么,控制团队该干什么,这个新角色正适合。最后,我们把项目经理角色转变成全职工作,这基于backlog 中巨大的数量以及客户对于下一步做什么的不断更改的需求。

评估

我们制定了一项规则,只有当一个工作项被完成评估后才能上到看板白板上。我们这样做的理由是,我们不愿意用团队之前的绩效作为对未来工作的承诺,我们不愿意因为团队的现有速率而限制我们的潜能。

每个周一清晨,我们都会开一个小时的会(时间盒式的),让团队对backlog 中还未评估且具有最高优先级的项进行评估。在这个时间段内,团队尽可能多地对需要开展的工作项进行评估。评估的单位是理论天数(ideal days)。团队需要对看板白板中的所有活动都做评估,而以前我们仅仅对实际要开展编码的工作进行评估。

这样做的结果是,团队成员都能感到自己与所要交付的工作项紧密相关。由于所有的开发活动都被包括在评估过程中,这也迫使团队对他们将要进行的角色了解得更多。这也增加了团队的凝聚力。

因为我们在每个工作周的头上就做这样的评估会话,我们就能保证在这周之后的工作日中,不让团队再受到干扰,把精力集中在开发工作的交付上。

我们观察到优先级与评估之间是动态的关系,因为产品负责人可能会根据工作项完成的情况提高或减少工作项的优先级。例如,当客户发现在相同的时间内完成4,5 个更小的故事,客户之前认定是高优先级的用户故事可能变得不那么重要。

结论

项目会因为不同的理由出错。那些用传统的、预测计划的方式进行的项目更容易出问题。这篇文章提供了“拯救”出问题的“红”项目的大致思路。某些方式——例如去拥抱变更而非控制变更——似乎更客观。让团队自取下一步要工作的内容而非分配给他们,似乎有点奇怪。

然而使用这个案例提供的方法,让我们成功地把这个快要失败的项目变成质量优异、客户满意度高、对下步工作项有很强预见性的项目。在最初的2 到3 个星期里,我们就看到了正面的结果。在大约8 个星期后,团队之前的所有问题都已经找到根本原因,团队工作变得非常自主和有效。

同样重要的是团队的士气得到显著提高。在经历了被没有节制的新增需求干扰后,以及客户对于产品质量的控诉之后,团队终于有能力向客户证明,事实上,他们有能力开发出有价值的产品。

现在,团队在所有的开发项目中都是用看板方法。这帮助他们更有效地了解客户期望,以及更有预见地完成他们所承诺的交付。

看板不仅仅是拯救项目的工具,保证项目不发生问题的最佳方式就在于一开始就运用这些方法。

关于作者

Steve Andrews 是 Fountainhead Solutions, LLC 公司的创始人。他的梦想是运用敏捷方法及现代工程技术创建一个专注于高新软件方案开发的公司。

Andrews 先生作为方案开发战略计划的领导者有着超过 20 年的背景和经验。他是两个方面的专家,一是找寻方法最大提升团队效率并能最快、最省钱地为疑难杂症提出解决方案;二是帮助开发人员及用户改进生活质量,减少工作的苦恼。

Andrews 先生拥有美国范德堡大学的计算机科学和数学的学士学位。

查看英文原文 Using Kanban to Turn Around Distressed Projects


感谢侯伯薇对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2012-12-04 07:574152

评论 1 条评论

发布
用户头像
突然看到这篇文章,10年了,描述的现象至今依然是现实。
2022-11-10 06:36 · 吉林
回复
没有更多了
发现更多内容

生成式AI,引领AI从“换脸”到“造脸”

海比研究院

Vue进阶(幺伍捌):vue组包 CssSyntaxError unclosed bracket 错误解决方法

No Silver Bullet

Vue 11月日更

一招教你快速打造企业级数据可视化大屏

云智慧AIOps社区

开源 大前端 数据可视化 大屏可视化 大屏

手把手教你从零开始搭建个人博客,20分钟上手

老表

Hexo 个人博客 服务器 教程分享 11月日更

告警风暴来袭,智能运维应如何化解?

云智慧AIOps社区

AIOPS 告警 技术学习 智能运维 时序数据

lims实验室管理系统是什么?实验室信息管理系统介绍!

低代码小观

企业管理 管理系统 LIMS实验室信息管理系统 LIMS系统 信息管理系统

Mac 系统如何利用软链接在根目录创建文件夹?

程序员泥瓦匠

Mac 文件写入

《黑客之道》- kali LInux之WireShark抓包及常用协议分析

学神来啦

网络安全 Wireshark 渗透 kali

如何快速搞定第三方登录且易扩展?

Tom弹架构

Java 架构 设计模式

【Flutter 专题】20 图解 ListView 下拉刷新与上拉加载 (三)【RefreshIndicator】

阿策小和尚

Flutter 小菜 0 基础学习 Flutter Android 小菜鸟 11月日更

这一次,解决Flutter Dialog的各种痛点!

小呆呆666

flutter ios android dart dialog

Eureka 源码之启动过程

悟空聊架构

Eureka 源码剖析 悟空聊架构

pygame 中的图形绘制函数、帧速率和文字相关知识,简单的的不得了

梦想橡皮擦

11月日更

Gartner发布2021企业低代码魔力象限,Mendix连续三年第一!

J2PaaS低代码平台

低代码 数字化 低代码开发平台

一分钟带您了解,堡垒机主要功能有哪些?

行云管家

网络安全 服务器 堡垒机 等级保护

dubbo 配置 loadbalance 不生效?撸一把源码

捉虫大师

dubbo

Apache ShenYu源码阅读系列-基于Http长轮询的数据同步

子夜2104

网关 shenyu

【等保小知识】等保、分保以及关保分别是什么意思?

行云管家

网络安全 等保 等级保护 分保

kubernetes系列随笔01:云原生发展

Geek_cd6rkj

Kubernetes 云原生 弹性

Redis 核心篇:图解 Redis 为什么这么快

码哥字节

redis 后端 Java 分布式 11月日更

「The Monthly Echo」十月社区成长回顾

SphereEx

数据库 开源 ShardingSphere 技术沙龙 SphereEx

使用 Spring Boot 和 @SpringBootTest 进行测试

码语者

Spring Boot 测试 test

在推荐几款ins视频和图片下载器,支持安卓和苹果

So...

Instagram ins ig ins视频和图片

苏杰:爆款产品是把基本动作做到位的结果

博文视点Broadview

图解Java线程状态转换

程序猿阿星

Java并发 线程 线程状态

第四模块作业-设计千万级学生管理系统的考试试卷存储方案

彦欲

架构训练营

工程师什么时机最合适选择跳槽?

程序员泥瓦匠

面试 加薪 跳槽 升职

恒源云(GpuShare)_【功能更新】镜像市场上线

恒源云

深度学习

【LeetCode】求众数 IIJava题解

Albert

算法 LeetCode 11月日更

Python代码阅读(第51篇):判断给定的数是否在给定的范围内

Felix

Python 编程 Code Programing 阅读代码

2021DevOps国际峰会·北京站|龙智展位盛况回顾

龙智—DevSecOps解决方案

DevOps Atlassian

拿看板拯救你——我的“红”项目_研发效能_Steve Andrews_InfoQ精选文章