跳转至

Lecture 3 敏捷软件开发

增量开发可以包含「迭代」和「敏捷」两种类型。其中,敏捷是指快速软件开发,顾名思义,就是要快速的产出有用的软件。

敏捷开发的主要特点是,规格说明、设计、实现三个过程交织在一起,不像瀑布模型那样在最开始就把详尽的说明搞好了。

敏捷开发需要 客户参与,以便获得需求变化的快速反馈。通过聊天等不太严格的交流,可以免去撰写文档的麻烦。

敏捷方法

敏捷宣言 Manifesto for Agile

由敏捷方法的主要提出者发表的敏捷宣言,如下:

  • 个体和互动 高于 流程和工具(Individuals and interactions over processes and tools)
  • 工作的软件 高于 详尽的文档(Working software over comprehensive documentation)
  • 客户合作 高于 合同谈判(Customer collaboration over contract negotiation)
  • 响应变化 高于 遵循计划(Responding to change over following a plan)

也就是说,尽管右项有其价值,我们更重视左项的价值。

英文原文 官方中译

敏捷开发的原则

  • 客户参与(customer collaboration):客户应当紧密参与到整个过程中,提供新的系统需求及其优先级,并对系统迭代进行评价
  • 拥抱变化(embrace change):系统需求随时都会变,要尽量更好的融入这些改变
  • 增量交付(incremental delivery):软件开发和交付是增量的,客户需要描述对于每个增量的要求
  • 保持简洁(maintain simplicity):自始至终,无论是软件本身还是软件过程,尽量保持简洁,不要让系统太复杂。比如,软件写好交付就完事儿了,文档不用搞太麻烦。
  • 人而不是过程(people, not process):开发团队成员应当充分发挥技能,按照自己喜欢的方式进行工作。

极限编程 eXtreme Programming

是一种注重于编程技术、团队的沟通与合作的开发风格。

极限编程的原则(14 条)

参考知乎

  1. 人性化(humanity),每个人都尽可能发挥自己的价值
  2. 经济化(economics),系统和团队要注重经济价值
  3. 互惠互利(mutual benefit),每一项任务尽量让所有人收益,提倡先测试再编码等
  4. 自相似性(self similarity),将一个解决方案结构应用于新的场景,即使颗粒度不同
  5. 改进(improvement),没有绝对完美,应当持续改进
  6. 多样性(diversity),所有人的意见都应当被重视,不能因为跟自己不一样就排斥
  7. 反省(reflection),也就是反思之前成功或失败的原因
  8. 流(flow),小增量,持续集成,一段工作要连续,而不应离散
  9. 机遇(opportunity),将面对的问题视作提升与改变的机会(能力、关系等)
  10. 冗余(redundancy),用多种方式解决困难(比如结对测试),以此保障可靠性
  11. 失败(failure),不要惧怕失败,假如有三种方案不知道选哪一个,都试试
  12. 质量(quality),不能追求速度从而牺牲产品质量
  13. 小步(baby step),一次只测试一个东西,一次集成只是一段小修改
  14. 接受责任(accepted responsibility),责任不是分配的,是自己决定是否要接受的

极限编程的过程

  1. 首先,产品经理、用户(可能也包括开发者)写下用户卡片
  2. 开发团队对每个用户故事进行评估、计算时间成本。如果太久,就让用户细分故事;如果没看懂,就 init 一个 spike
  3. 产品经理与用户共同商讨决定,大的背景(可能是一个季度 quarterly)要做哪些事情
  4. 开发人员再选取少量可有可无的任务。如果进度比较快就做,进度慢就不做,放在一周的计划内进行。这叫松弛(slack)

于是极限编程的周期,基本就是:选取几个要实现的用户故事、拆解成任务、开发、集成并测试、发布、评估。

开发者每天要做什么?

  • 早上先开个短会,分析一下,今天干什么
  • 找个同事开始 结对编程。一个思考,一个实现,适时交换;而且每行代码都俩人看,安全
  • 编写测试。测试先行,也就是说正式编码前要先把测试编写好。这样编码就会轻松
  • 编写代码。通过测试后,还要进行一定的重构,满足代码风格规范等
  • 集成,然后测试,如果跑过了,那么任务就完成了,可以下班或者干点别的,否则丢弃

用户故事

用户故事(user story) 是从用户的角度来描述用户渴望得到的功能。

开发者从众多用户故事当中选取一个,将其划分成若干个任务,将其实现、测试、发布,然后再选一个用户故事,如此循环。

可参考 简书 上面的解释。

用户故事撰写格式

作为 我想要做 ,以便 <实现 zzz 的好处>。此外,也可以包含一些备注等。

一条用户故事只能有一个角色。

Scrum

是一种敏捷模型,得名于橄榄球赛(一大堆人围成一个圈圈,共同努力,想要抢球)。

而且 Scrum 是比较透明的,流程对所有成员都可见。

Scrum 流程

1. 愿景 vision

这个阶段涉及到几乎所有利益相关者。他们要分析以下问题(愿景):

  • 这个软件系统是干嘛的?
  • 这个软件系统有啥好处?
  • 用户是谁?
  • 有哪些高级功能?
  • 要遵守哪些约束?
  • 有哪些更高的目标?

然后把得出的功能需求等,写进用户故事。

2. 产品待定项管理 product backlog management

待办事项(backlog) 实际上就是一个包含了优先级的 todolist。开发团队负责评估,而产品 负责人(owner) 负责确定优先级。

backlog 是动态的,其中可以随时添加新项,这就是变更的引入。引入变更之后,可能要重新评估优先级。

backlog 当中的每一个 item,都要有描述信息、优先级信息、评估、point、验收标准等。根据其属性,可以分入若干个大类(theme)中。而优先级较高的 item,通常描述会更清晰。

3. 从 backlog 当中选择 item 并准备进行 sprint

这是一个准备阶段,几个小时就完事儿了,主要是要为下一个迭代周期做一个初步的思考和规划。比如,思考这次迭代需要完成什么目标。

然后开发者从 backlog 当中选出一个或几个 item,把他们加入冲刺待办事项(sprint backlog),准备冲刺。

冲刺待办事项当中的每一个 item 要做的比较细,精确到每天,于是可以用来监视开发进度。可能是以用户故事的形式体现的。下图就是一个冲刺待办事项的例子。

目前是第一轮冲刺,这一轮还有 17 天。截至目前,一项已完成,正在做两项,还有三项未开始。它们加起来一共是 28 points,这些 points 表示了每一个 item 估计的时间成本。

4. 冲刺 sprint

这个阶段所有人像一个团队开始工作。

一般冲刺过程是一个月左右,不能太短,也不能太长,于是风险就被降低了。

这个过程当中,不允许有变更,这为开发人员提供了短期的稳定环境。除非发生意外,或者管理人员说,的的确确有更重要的事情需要去做。

每个冲刺的最后阶段是回顾(retrospective)。回顾之后,下一个冲刺就开始了。

每日 scrum 例会

冲刺过程中每天都要召开例会,十来分钟,所有人凑在一起,由 scrum 主管(master)(相当于产品经理)来主持会议。

会议中需要分析三件事情:

  • 昨天干了什么
  • 今天要干什么
  • 有没有遇到困难

这不仅能实现进度的检查,还可以对以后做出更好的规划。

冲刺中的用户故事

在冲刺待办事项当中,列出所有的用户故事,方便查看管理。

右侧小数字(point)代表的是这一条任务大约需要耗费多少时间,而非优先级。

根据用户故事画出燃尽图(burndown chart)

燃尽图是用于表示剩余工作量的工作图表,由横轴(X)和纵轴(Y)组成,横轴表示时间,纵轴表示工作量,即上述的 points。

一般燃尽图当中应当至少有两条线,一条表示理想状态下的剩余工作量,一条记录实际。于是还可以显示出,每天的进度是快于理想值,还是慢于计划。

5. 评审 sprint review

这个会议也是只有几个小时。会议主持人依然是主管(master),而负责人(owner)负责说明这个阶段做了什么。利益相关者 可能也是在场的。主要就是演示、交付增量。

除此以外,还可以讨论一下待办事项、预算等一些事情。

6. 回顾 sprint retrospective

这个 retrospective 和 review 比较容易混淆。retrospective 主要是对内部的(其他利益相关者不应该参与),开发人员相互总结、反思、鼓励,思考哪里可以改进,等等。

DevOps

不是重点内容,了解一下即可。

DevOps(Development 和 Operations 的组合词),即同时重视开发和运行。

它希望需求变更很少,可以把更多精力集中在测试上,以此来保障更好的产品质量和更快的交付周期。

由于测试比较多,DevOps 很可能依赖于自动化工具。这个自动化工具不仅仅是自动 verification,还要自动 validation。

敏捷开发总结存在的问题

  • 并不适用于嵌入式系统(瀑布模型)或大型项目(没有正式合同)
  • 敏捷开发注重的是项目的开发过程,对日后的维护,不太关注
  • 只适用于小型团队,对于大型团队(尤其是多个不同办公地点的团队)搞这个很不方便