一只猪的 Scrum 开发经历

Posted 悦思悦读

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一只猪的 Scrum 开发经历相关的知识,希望对你有一定的参考价值。

Scrum 是一种方法论,有很多术语、定义、规则。

本文不是讲 Scrum 理论,而是从应用的角度,讲述我自身 Scrum 实践的经验体会。理论运用到实践中时,一定会有所变化。本文中根据我切身经历,对理论略作删减。

1. 从瀑布到敏捷

1.1 瀑布模型

2010年,我已经做了好几年程序员,不过所遵循的开发流程一直是传统的瀑布模型。

瀑布模型,顾名思义,就是将软件开发的过程分为:需求分析、设计、实现(编码)、验证(测试)和部署维护(发布)几个阶段,顺序执行。

做完一个阶段再进入下一个阶段,如同瀑布从上流到下流。

阶段的计时粒度一般是月,把一个流程跑完,再小的项目也得几个月。

每个阶段都有大量的文档需要完成:

  • 需求阶段有需求分析文档;

  • 设计阶段是设计和体系结构文档;

  • 实现阶段是模块详细设计、功能文档,和测试规格说明;

  • 测试阶段要出测试详细流程说明,测试用例说明和测试报告;

  • 到最后发布又要写针对用户的功能说明……

笔者亲历:曾经有个从需求到发布总共历时九个月的项目,各阶段均严格执行瀑布模型。总共写了几万字的文档,最终实现代码,只有4000余行。

一只猪的 Scrum 开发经历

呵呵,简直搞不清自己是 coder,还是 writer。

1.2 敏捷开发

2010年面试新公司的时候:

对方问:你知道 Scrum 吗?

我说:不知道。

对方说:那是一种敏捷开发方法,我们要用 Scrum 方法开发产品。

我:噢嚄嚄……

进入新公司之后,第一次开会,看到了下面这副漫画:

一只猪的 Scrum 开发经历

鸡说:猪,我在想我们应该开个餐馆。

猪:叫什么名字呢?

鸡:叫“火腿和鸡蛋”怎么样?

猪:不了,谢谢。这样的餐馆,你只需要参与,而我得把自己全搭进去。

1.3 这是什么意思啊?

一只猪的 Scrum 开发经历

老板告诉大家:我们团队要敏捷开发软件了,选用 Scrum 方法。所以,从今天起,在坐的各位 Team Member,你们就是猪啦!

一只猪的 Scrum 开发经历

2. 什么是敏捷开发?

跳过我得知消息那一刻的心理活动。我们先来了解一下,什么是敏捷开发,什么是 Scrum。

其实,敏捷开发的雏形和前身出现得很早。1957年,迭代和增量式软件开发方法就被提了出来,甚至比“软件工程”出现得还早。

后来瀑布模型在很长时间内成为开发的主流。

到了1990年代,随着应用软件开发的兴起,传统重量级软件开发方法越来越多的遭到批评,发展出了许多轻量化的细微化开发管理方法:

  • 1991年,迅速应用程序开发;

  • 1994年,统一处理程序与动态系统开发法(DSDM);

  • 1995年,Scrum 方法;

  • 1996年,极限编程;

  • 1997年,功能驱动开发;

  • ……

虽然那时候还没有统一公认的术语描述它们,其实它们都属于敏捷软件开发方法。

2001年,十七名软件开发人员在美国犹他州的雪鸟度假村会面,讨论迭代和增量式进程的、非传统的轻量级软件开发方法。

讨论的结果是,由 Jeff Sutherland,Ken Schwaber 和 Alistair Cockburn 发起,一同发表了著名的“敏捷软件开发宣言”(Manifesto for Agile Software Development),定义了相关的价值和原则——“敏捷(Agile)”方法,由此得名。

这份宣言本身就非常的敏捷,简短如斯:

一只猪的 Scrum 开发经历

这几句话看起来像是口号,但贯彻得到实践当中后,确实带来了和在传统瀑布模型下开发软件截然不同的局面。

敏捷软件开发中最广泛应用的两种框架是:Scrum和Kanban。

本文专注于 Scrum。下面我们来看看什么是 Scrum。

3. Scrum 几个基本概念

Scrum 这个词,是橄榄球运动中列阵争球的意思。它被用作术语,代指一种敏捷软件开发方法学。

这种方法学同样可以用于运营软件维护团队,或者管理计划

Scrum 定义了几种角色,多个会议,一套工具和一个流程。

3.1 角色

这一系列概念中,最重要的是角色:Scrum 通过角色来定义不同软件开发参与者之间不同的职责和“卷入深度”。

下图展示了 Scrum 角色:

一只猪的 Scrum 开发经历

其中的核心角色有:

  • Scrum Master(SM):Scrum 教练和团队带头人,确保团队合理的运作 Scrum,并帮助团队扫除实施中的障碍;

  • Project Owner(PO):确定产品的方向和愿景,定义产品发布的内容、优先级及交付时间,为产品投资报酬率负责;

  • Team :跨职能的开发团队,拥有交付可用软件需要的各种技能(开发、测试、部署、运维)。推荐人数5-9人。

除了上述角色,在软件开发过程中还有一些其他角色,比如:

  • Customer(用户及相关人员):个人用户、商业客户,或相关业务运营商等,与软件开发相关,但并不直接参与开发过程的人。

  • Executive Management(非技术管理者):为产品开发团队搭建环境的人。

由于不同角色对于项目的投入深度不同,他们又被分为两类:猪和鸡——对,就是上面漫画里所提到的猪和鸡。这副漫画还可以表述成一个谜语:

一只猪的 Scrum 开发经历

谜面:在一份培根蛋早餐中,猪和鸡的区别是什么?

谜底:鸡参与,猪送命。

猪是全身投入 Scrum 过程中的各种人物,他们承担实际工作。就像上边那个笑话里的猪,要把自己身上的肉贡献出来。而鸡并不是实际 Scrum 过程的一部分,但又必须考虑他们。

按照这个原则很容易看出,上面的几种角色:

一只猪的 Scrum 开发经历

其中猪是核心。

一只猪的 Scrum 开发经历

3.2 冲刺(Sprint)

Sprint 是 Scrum 流程的一个核心概念。这个词直接翻译成中文是冲刺。但作为 Scrum 术语,Sprint 指一次原子迭代。

一只猪的 Scrum 开发经历

一个产品开始采用 Scrum 开发时,务必要定好一个 Sprint 的时长。参考时长是一周到四周,比较常见的是两周或三周为一个 Sprint。

每一个 Sprint 从计划(Plan)开始,到回顾(Retrospect)为止。每个 Sprint 结束时,Team 都要提交一个产品增量(Product Increment),这个产品增量自身是功能完整质量有保障的,而且不会给之前的产品带来回归问题。

换句话说,每个 Sprint 结束,都能得到一个可发布的版本。

当然,也有非常激进的 Scrum 团队,要求每天结束时产品都是可发布的。不过大多数情况下,要求产品以 Sprint 为单位更新可发布就可以了。

3.3 会议(Meeting)

Sprint 由计划开始,到回顾结束。因此:

  • 在一个 Sprint 开始时,团队要召开计划会议(Planning Meeting),用于对现在这个 Sprint 做计划。

  • 在一个 Sprint 结束时,团队要召开回顾会议(Retrospective Meeting),用于评价这个 Sprint 的成果,总结经验教训。

NOTE:按照比较严格的理论,Sprint 结束时要有一个评审会议(Review Meeting)和一个回顾会议(Retrospective Meeting)。

但是,鉴于 Sprint 本身体量很小,其实没必要开这么多会。这两个会议完全可以合二为一成为回顾会议。

  • 在 Sprint 进行中的每一天,团队都要召开每日 Scrum 会议(Daily Scrum Meeting),又称站会(Stand Up Meeting)。在站会上,每个团队成员需要回答三个问题:

    1. 完成你的目标存在什么障碍?

    2. 今天你打算干什么?

    3. 昨天你干了什么?

一只猪的 Scrum 开发经历

Stand Up Meeting 是 Scrum 各种会议的重中之重。很多“宽松 Scrum”团队(后面会讲),真正召开的,就只有 Stand Up Meeting。

每天大家在一起互相交流做了什么,没做什么,有什么需要帮助。是一种非常高效的交流方式和监督机制。

不过有一点要注意:Stand Up Meeting 是通气会,不是讨论会。

不管有什么障碍、困难或者疑惑,把是什么说出来就可以了。具体是怎么回事,有什么想法,应该在散会后找相关人员直接讨论,而不是在会上讨论。

为了做到这点,同时强调持续性和提高效率。Stand Up Meeting 需要遵循几个原则:

  • 每天在固定地点准时开始。会议全长不得超过15分钟。

  • 所有猪都必须参加。大家站立成一个圈,按时针顺序轮流发言。

  • 鸡可选择性参加。如参加,只能旁听,不能发言。

3.4 功能点

开发工作总离不开对功能的阐述。在瀑布模型中,从需求文档到设计文档,到设计细则都是围绕此进行的。

到了敏捷开发,虽然我们“关注工作的软件,而不是详细的文档”——也不能连要做什么都不知道。这就需要把要做的东西写下来。

当然不是写笨重冗长的文档,而是写得越短越好。

相对于以前动不动就是半年一年的瀑布迭代,一个短小的不足一月的 Sprint 就要完成之前从需求到发布的全过程,所有的工作都被细分了。

这种细分直接体现在对功能的描述上:功能模块被细化成了功能点。

这些功能点在 Scrum 中被称为故事(Story),一个故事可以被进一步分为多个任务(Task)。

不同团队对于故事和任务的定义可能有所区别。有些团队把一个人一次独立完成的一个功能点称为故事,另一些团队则将这个小小单位称为任务。为了避免歧义造成的争论,我们在此不用 Story 或者 Task,而是用“功能点”来进行代指。

一只猪的 Scrum 开发经历

4. 工具

4.1 Dashboard 和 Backlog

整个 Sprint 的工作,都是围绕着功能点进行的。

每个 Sprint 开始时的计划会议上,团队列举出本 Sprint 所有要做的功能点。

在之后每天的站会上,每个团队成员对应昨天做完的工作和今天要做的工作,领取/更新/提交自己的功能点。

这样,就需要有个工具来管理功能点。这个工具,我们一般叫做 Dashboard——中文直译为仪表盘,但是显然不能解释清楚它的意思。

Dashboard 其实就是这么个东西,一块板,分成几个栏对应不同状态,每栏里有一些功能点。

Dashboard 具体的形式很多,可以这样:

一只猪的 Scrum 开发经历

也可以这样:

一只猪的 Scrum 开发经历

最简单也可以这样:

一只猪的 Scrum 开发经历

到了 Sprint 结束时的回顾会议,仍然可以用 Dashboard 来评判这一 Sprint 的成果。

分栏的标准可以沿用之前的 To Do、In Progress、Done,也可以用 Team Member 满意与否来衡量:

一只猪的 Scrum 开发经历

功能点的创建和实现通常不同步,一般在整个项目开始的时候,功能点会集中创建一大批,然后再慢慢完成。

这个时候就会有大量的功能点被堆积在 To-do list 里,或者专门放在一起,不进入当前 Dashboard。这个时候,未开始实现的功能点的列表,就被称为 Backlog

Backlog 又可以细化为:

  • Product Backlog:用来记录整个产品要做什么;

  • Sprint Backlog:用来记录这个 Sprint 要做什么;

  • Block List:用来记录有什么障碍影响了当前的进度。

4.2 Pointing System

功能点未必是均匀的,可能有的比较复杂繁琐,需要时间比较长,有的则比较短。这个时候就需要一个系统来衡量不同功能点所需要的开发代价。

一种比较通用的方法是点数系统(Pointing System),使用点数(Point)来标记每一个功能点。

Point 计数可以采用斐波那契额数列:1,2,3,5,8……

一只猪的 Scrum 开发经历

具体一个 Point 对应多久的工作可以团队自己定义(定为1人天是最方便的),不同功能点 Point 值不同,就表现了所需投入不同。

比如,一个 2 Points 的功能点,就被认为需要2倍于 1 Point 功能点的投入。

每次在开计划会议的时候,Team 先集体对本 Sprint 中要做的功能点进行打分(复杂度评估)。常用方法是大家同时报一个点数,然后求均值或者以大多数人选定的为准。

如果有个别人与大多数人的评定相差太大,需要陈述理由,然后做出是否修改功能点的决定。

有一种点数扑克可以用来帮助记点数,报点数时每人亮出一张扑克。不过一般用不着这么麻烦,伸手指头就行了。

一只猪的 Scrum 开发经历

到 Sprint 结束时,计算出已经完成的功能点的总点数,和团队中每个人完成的点数,与计划会议的评估结果相对应,可以看到本 Sprint 的计划完成情况。

4.3 燃尽图

Sprint 初始时有许多待实现的 Points,每天 Team 都在工作,以减少 Points。如此一来,就造成了点数的下降。

用图表将这种下降趋势表现出来,就是燃尽图(Burn down chart)

一只猪的 Scrum 开发经历

总览

  • 三类猪:Product Owner、Scrum Master、Team;

  • 三种会:计划会议(Planning Meeting)、回顾会议(Retrospective Meeting)、站会(Stand Up Meeting);

  • 一个冲刺(Sprint)

  • Dashboard、Backlog、Story/Task、Points、Burn Down Chart ……

这些要素结合起来,就成了 Scrum:

一只猪的 Scrum 开发经历

几个问题

关于 Scrum,有几个常见问题,在此集中回答一下:

Q:采用了 Scrum 方法开发软件,是不是就可以不写文档了?

A:虽然从理论角度出发,Scrum 方法和是否写文档没有什么直接关系,不过从实践角度看,大部分采用 Scrum 的团队确实在极大程度上减少了文档的书写量。

当然,严肃点,Scrum 肯定还是有要写的东西的。无论怎么简化,Product Backlog、Sprint Backlog,和 Block List 总是跨不过去的。

一只猪的 Scrum 开发经历

Q:Point 估算工作量靠谱吗?

A:这点其实和产品类型比较相关。如果是相对简单或者实践性的产品(比如一旦需求明确,具体应该怎么做有现成的经验可循的产品),功能点可以拆分得比较平均和细小。

如果是较多研究/探索性质的项目,或者团队对于如何实现没有现成经验,需要大量的学习和尝试,那么很难将所有功能点分割均匀。

相对而言,整个 Scrum 方法,都更适合前一种情况。

比较理想的情况下,当一个 Point 相当于一人天工作量时,最好不要出现大于3或者2的功能点。如果有5甚至更高的点出现,就需要对其进行进一步拆分,尽量使得每个点的完成量在2天或以下。

记点数是一种用来衡量工作量的方法,衡量工作量是为了做管理。所以,应用 Point 估算最关键的不是如何打分记点数,而是如何在团队中达成共识!

一只猪的 Scrum 开发经历

Q:修 Bug 算不算工作量?

A:这点不同团队的处理不同。

比较激进的 Scrum 团队认为修 Bug 不应该算点数(Point),因为 Bug 本来是不应该存在的,是开发的失误导致了 Bug。

而在评估一个功能点时,所给出的点数,是指将此功能点开发至正确提交时的全部投入,修 Bug 已经包括在里面了。

这样说虽然有一定道理,不过在实际操作中很难实现。具体是否算点数,是否把修 Bug 放在每个 Sprint 的计划中,还要团队自己定夺。

一只猪的 Scrum 开发经历

Q:团队的 Velocity 和产品质量之间有怎样的关系?

A:因为在 Scrum 中计算工作量最常用的工具是燃尽图,因此,实际上被用来衡量一个团队的工作量(Velocity)的,是每个 Sprint 完成的点数(Point)。

当然,如果从理论角度说,工作量和产品质量是无关的两个因素。

但是因为 Scrum 方法在实践中的经典场景是一些需要迅速迭代的产品。而在实际工作中,许多团队其实并没有独立评价体系来评价产品质量。

因而,在某些情况下,velocity 会成为评判产品质量的一种参考。

当然,这样可能挺不靠谱的,[悄悄说] 。  

一只猪的 Scrum 开发经历

与其他方法结合

Scrum 方法自身反复、快速迭代的特点,以及对个体间加强互动的要求,导致它和某些软件开发方法,有一种天然的契合。比如下面这两种。

· 测试驱动开发(Test Driven Development/TDD)

TDD,简单的解释就是先测试再开发。还没开发出来怎么测试啊?所以在实践中做得是:先写测试用例(Test Case),再写功能代码。

一只猪的 Scrum 开发经历

先写测试用例,也就定义了对应要开发功能的输入输出。再去写功能代码,完成开发后运行对应测试用例。

局部测试不通过,则改 code。局部测试通过,则运行全部测试用例,以确定是否有回归问题,有的话及时 fix。

· 结对编程(Pair Programming)

故名思意:两个人结成一对(对子)编程。具体做法是两个人守着一台计算机,盯着同一个屏幕,一个人写 code,另一个人看。

写的人叫司机(driver),看的人叫导航员(navigator)。司机在写的过程中应该不断解释自己在干嘛,正在写的 code 的功能和如此写的出发点是什么。而导航员如果觉得有不妥之处,可以指出;有不明白的地方,也可以提问。

一只猪的 Scrum 开发经历

司机和导航员不是固定的,可以定时(每隔1小时/半天/…)轮换。

司机和导航员的搭配也有多种:

  • 新手和资深工程师 pair,从0距离的口传心授中获取知识,不懂之处即时问答——这可以说是提高水平的最短路线。

  • 水平接近的工程师之间可以交换不同领域的知识,以及编码本身的技巧方法。

  • 资深员工则具备了随时向新人分享技术心得教学相长的机会。

理想与现实

我们从理想化的角度,来看看 TDD 和 Pair Programming 的好处:

  • 测试先于开发,保证了自动化测试的全覆盖,节约了人力成本,且可以在短时间内反复迭代回归。

所有这些,最终都以产品开发的高效,质量的稳定,以及可持续发布作为体现。团队和个人,达到了双赢。

  • 结对编程的带来的好处是:团队成员整体水平趋于整齐,每个人不再有“专属领域”,消除/减少了单点依赖,产品不会再因为某个人生病、休假或离职而被阻碍进度。

而且,两两结对,不仅提高了每个人的效率,还保证了一个人写的代码总是有人 review,从根本上提高了代码质量。

一只猪的 Scrum 开发经历

不过,惯常情况:理想很丰满,现实很骨感。任何事情都是有适用范畴的。通过下面的例子,我们来看看,真的在现实中运用它们,是什么样子。

实际案例

· 纯 Scrum 实例

这是一个我亲身经历过的团队,在其中工作了近一年时间。

团队的一天

早上大家集合在一起,开始站会。产品经理(担任 Scrum Master)把当前 Sprint 中需要完成的story写在便签上,贴到白板上。

白板上的Story涵盖前端、后端、数据存储和基础设施等方面。

工程师(Team Member)逐一简要陈述昨天的工作进展和遇到问题之后,就两两结对,从 open 的 story 中选择今天要做的。

一只猪的 Scrum 开发经历

之后开始全天的 Pair Programming。

参与 Pair Programming 的工程师(从 title上)包含 Software Engineer 和 Software Quality Engineer。然而实际上,没有 Dev 和 QA 的区别,没有前端和后端的区别,大家做的都是同等的事情。

比如:今天 Alice 和 Bob 结对,共同完成一个 Data Exploration 的 story,他们会一起编写新的  API,实现后端访问/处理数据的代码,和前端展示数据的代码 。

明天,他们则要分开,和新的伙伴继续组合,Alice 可能和 David 共同进行数据库访问框架的重构,而 Bob 也许和 Candy 结对改进 Integration Test Framework。

一只猪的 Scrum 开发经历

对于 story 的实现,遵照添加 test case -> 实现 story 功能 ->运行测试,确保新添加 case 和旧有 case 完全通过 -> 将测试和功能代码迁入 repository 的顺序进行。

一天结束时,大家更新各自负责的 story 的状态,将其从 To do 栏移至 In progress 或 Done。然后下班回家。

适用范围

这一套,不是什么公司都能玩得了得。

个人观点,纯敏捷所适用的范畴是:互联网产品(有快速迭代、短周期发布的需求,架构相对清晰明确,允许采用开源框架和技术)和中小规模本地团队。

如果团队人数超过20人或者团队成员分布在不同办公地点,则效果将大打折扣。

一只猪的 Scrum 开发经历

当产品开发难度相对较大,开发人员除了干活,还需要大量的学习和思考的时候,测试驱动开发和结对编程就都不太合适了。

尤其是后者,当需要检索查询、阅读资料时,两个人绑在一起就是灾难。

强制管理

还有一点:TDD + Pair Programming 真的在现实开发中应用起来,必须借助来自管理层的行政命令——即这样做是必须的,是规定,而非工程师的自愿选择。

一旦被给予“自由选择”的权利,可以 pair 或者 solo,不出三天,所有工程师就又回到原始单兵作战的状态了。

这也是实践中的教训。

松散敏捷——各取所需

“松散敏捷”并非一个术语,我用它来形容那种“非纯”敏捷团队。

由于“纯度”不同,不同团队从 Scrum 中汲取的内容不同。

不过一般而言,只要声称 Scrum 的团队,一定会有站会(Stand Up Meeting)。配合站会,就会有 Backlog 和 Dashboard

其他的会议、工具,甚至角色分配,就不一定了。

很多“松散 Scrum”团队,根本没有 PO,SM 概念,也不关心猪和鸡的区别。

Stand Up Meeting 之所以这么受欢迎,自有其坚实的基础。

在瀑布时代,也有很多团队要求成员写周报,甚至日报,用来说明自己(1)做了什么,(2)要做什么,(3)以及有什么困难。

对于职场人来说,这三条是管理的最基本。了解了它们,老板也就对自己的团队有了起码的把握。

一只猪的 Scrum 开发经历

当面交流又是最有效的沟通方式。如此一来,不仅仅是软件开发,站会及其工具,完全可以成为一种通用的管理方法,应用在各种领域。

不过这里有点需要注意:如果没有特意地控制长度,站会很可能开成讨论会。特别是在讨论技术细节或者引起分歧的时候。

敏捷引发的变化

敏捷为软件开发带来了,仅仅是过程和方法的转变吗?显然不限于此。

· 持续发布

传统软件——单机版,或者部署在大型组织内网上的服务器端产品——的发布周期是按月,甚至按年计算的。

到了互联网时代,各种产品通过网页或移动端 App 发布,更新不再需要下载安装,可以实现无缝更新。如此一来,后台的功能部分也就可以在任意时间进行修改。

互联网产品自身的特点也对随时发布更新提出了需求。由此引出了持续发布的概念。

持续发布是指频繁的发布产品更新。在实践中,一般指发布周期按天,甚至按小时计算。

一只猪的 Scrum 开发经历

敏捷开发方法,为持续发布提供了方法论上的支持——微迭代的理论,辅之以自动化测试、测试驱动开发等技术,使得每日(甚至每次更新后)的产品不仅功能自洽,而且都经过测试。只要部署到产品环境,就可以直接服务于用户了。

对模式、人员业务的影响

Scrum 对软件产品开发模式,人员配比以及业务与技术的关系,都产生了影响。

开发人员不再是被动接受产品规格说明,仅作为一个纯粹的实现者存在。而是要参与到功能点切分、分配中去,可以直接与 PO,SM 交流,甚至影响对于需求的解读。

由于自动化测试需要开发测试框架和工具,对测试人员 Skill Set 的要求与传统大相径庭。

反过来,开发人员也可能会投入到测试框架、工具或者测试用例的编写中(TDD)。

这就要求 Scrum 团队融合开发和测试,很多团队干脆不区分开发和测试。

再者,持续发布导致很可能部署和运维人员也存在于团队中,或者干脆由开发人员直接兼任。

如此种种,导致 Scrum 团队是跨职能的团队,甚至人员本身就是跨职能的。

一只猪的 Scrum 开发经历

另外,功能点细化、微迭代,以及大量开源框架、自动化工具的引入,使得原本看似高难的开发工作,逐渐降低了门槛。

敏捷开发造成纯技术投入在产品中的占比相较以往有了很大下降。产品开发的中心从技术向业务迁移。

Scrum 不是银弹

当然,软件开发(其实任何事都一样)没有银弹,不存在通行的方法。

Scrum 可以缓解一些问题,但有其适用场景。而且,只要有所为,必然有所不为。有适用,就有不适用。Scrum 也不可能适合所有的产品、团队、场景。

没有最好,只有最合适。大家在实际应用中还是要从自身真实状况出发,没必要赶技术或者理论的时髦。

具体的理论在应用时也需要定制化的实践。不是生搬硬套规则条款就可以解决问题的。


以上是关于一只猪的 Scrum 开发经历的主要内容,如果未能解决你的问题,请参考以下文章

我的Thoughworks-Scrum经历点滴

卡尔曼滤波

记一个无所不能的Scrum Master

组合数

深入核心的敏捷开发

SCRUM之Sprint燃尽图实例分析一