本节书摘来自华章出版社《SAFe 4.0参考指南:精益软件与系统工程的规模化敏捷框架》一书中的第3章,第3.13节 作者[美]迪恩·莱芬(DeanLeffingwell),更多章节内容可以访问云栖社区“华章计算机”公众号查看。

3.13 故事

故事,作为一种“行话”,能够使用户和开发者充分理解,达成一致,从而高效地协同工作。

—Bill Wake,极限编程联合发明人

摘要

故事是敏捷开发过程中用于定义系统行为的主要工件。故事不是需求,它是对期望实现的较小功能的简明描述,通常从用户的角度,使用用户的语言来进行编写。每个故事都可以支持系统功能的小型和纵向切片实现,从而可以支持系统的增量开发。敏捷开发中,故事基本上取代了传统的需求规范文档,也可以在后期用需求规范文档汇总成必需的传统需求文档。

故事对于要实现的意图提供了足够的信息,可以让业务人员和技术人员充分理解。故事是“承诺进行交谈”的,它作为一个载体,可以对系统行为和影响进行全面的讨论,而对细节的讨论,可以推迟到故事准备就绪进行实现时再进行。通过接收标准的确定,故事在实现过程中变得更加明确,而系统的质量也得以保证。接收标准可以在接收测试的过程中被自动捕获和验证。不论是最初描述故事的时候,还是后期方案演进的时候,这些测试都可以保证系统的功能被正确地实现。这是SAFe内建质量实践的至关重要的一环。

使能故事是另一种类型的故事。它们不是用来描述系统功能的,而是用来支持探索、架构和基础设施等相关方面的工作,并将这些工作进行可视化呈现。

详述

SAFe框架提供了一个四层的体系结构,用于描述功能层面的系统行为,包括:史诗(Epic)>能力(Capability)>特性(Feature)>故事(Story)。它们和非功能性需求一起构成了敏捷需求(系统行为)的描述要素,用来定义系统和解决方案意图,建模系统行为,并构建起敏捷架构跑道。

史诗、能力、特性和使能,它们被用于描述更大的意图行为,而细节的实现是通过故事来描述的,故事是团队待办事项列表的组成部分。大多数故事来源于项目群待办事项列表的业务和使能特性,也有一些是团队根据自己的情况创建的。

每个故事都是一个小的、独立的行为,可以通过增量实现向用户和解决方案提供相应的价值。故事是功能的纵向切片,有助于确保在每个迭代都交付新价值。为此,就需要对故事进行必要的拆分,使其能在一个迭代中实现。

起初,故事被写在一些索引卡片或者记事贴上。因为索引卡片是有形的实体,有助于在团队、故事和用户之间建立起联系,鼓励大家一起编写用户故事。这些卡片也是动态的,有助于将工作任务进行可视化,可以把它们贴在墙上或放在桌子上,重新排序、相互传递,甚至抛弃掉某些卡片。这些卡片可以帮助团队更好地理解其工作范围(“哇,看看这些故事,让我们接收这些工作吧”)和工作进展(“看看这些故事,都是我们在本次迭代内完成的”)。

虽然任何人都可以写故事,但是只有产品负责人有权批准故事进入团队待办事项列表和接收故事进入系统基线。当然,在整个企业环境中使用记事贴,不太容易进行规模化扩展,所以就出现了很多敏捷项目管理工具,用于辅助管理和跟踪故事。SAFe里有两种类型的故事,用户故事和使能故事,接下来将详细介绍。

故事的来源

在SAFe里,故事通常来源于业务特性和使能特性的拆分,如图3.13-1所示。

用户故事

用户故事是表达功能需求的主要方式,它们基本上替代了传统的需求规格说明书。(然而,在某些情况下,用户故事被用于理解和开发要实现的系统功能,而这些系统功能后期要被记录在传统的需求规格说明书里,以便检查功能的合规性、可追踪性,或者其他用途。)

用户故事以价值为中心,它着眼于用户而非系统,展示出用户的兴趣。为此,推荐的表达方式是如下的“用户之声格式”:

作为一个<用户角色>,我可以<活动>,以便<业务价值>

使用这种格式,团队可以持续地关注和理解谁正在使用这个系统,他们如何使用这个系统,以及他们为什么需要这个系统。应用这种用户之声格式,能够提高团队在该领域的胜任能力,他们可以逐渐地、更好地理解用户真正的业务需求。图3.13-2提供了一个例子。

虽然用户故事的格式比较通用,但也不是每个系统都与最终用户打交道。有时,“用户”是一台设备(如打印机)或者其他系统(如交易服务器)。在这种情况下,故事的描述可以采用如图3.13-3所示的格式。

使能故事

团队也需要开发一些技术方面的功能,这些功能可以用于实现许多不同的用户故事,或者用于支持系统中的其他组件。在这种情况下,故事可能不直接接触任何终端用户。这就出现了使能故事,使能故事可以支持探索、架构和基础设施建设,就像其他内容的推进器一样。在这种情况下,故事的描述就是从技术的角度,而非用户的语言了,如图3.13-4所示。

用户故事示例                  用户故事示例

使能故事可以包括以下内容:

重构和探针(与极限编程中的定义相同)。

构建或改进开发/部署的基础设施。

运行需要人工干预的任务(例如,检索100万个网页)

根据不同的目的,生成不同的产品或组件的配置

执行特殊类型的系统质量验证(例如,安全脆弱性测试等)

当然,使能故事和用户故事一样,可以进行演示,典型的做法是可以演示生成的工件,或者通过用户界面(UI)、打桩(stub)和模拟(mock)进行。

编写好的故事

3C:卡片(Card)、交谈(Conversation)、确认(Confirmation)

Ron Jeffries是极限编程的发起者之一,他提出了用户故事的3C方法。

卡片(Card)指的是用一张索引卡片、记事贴或使用其他工具,捕获和表明用户故事的意图。索引卡片很自然地提供了团队和故事之间的联系。卡片的大小从物理上限制了故事描述的长度,从而也限制了系统行为的早期特征。卡片也可以帮助团队“感觉”到故事涉及的范围,比如团队手中拿着10张卡片的感觉,与用眼睛看10行电子表格的感觉是有区别的。

交谈(Conversation)表达的意思是在团队、客户/用户、产品负责人和其他利益相关者之间“承诺进行交谈”。这是一些必要的讨论,用来决定为了实现某些意图所需要的细节行为。这些交谈也可能会产生其他形式的变化,比如模拟、原型、表单、算法、时序图等。交谈跨越了故事的整个生命周期:

待办事项列表的梳理

计划

实现

演示

交谈提供了共享的氛围,这是正式文档所无法提供的。交谈通过讨论功能的具体实例,让需求变得不再模糊。交谈也有助于发现一些没考虑到的情况或者一些非功能性的需求。有些团队也会在故事卡片的确认栏中记下他们将如何演示该故事。

对接收标准的确认(Confirmation)提供了明确的条件,用于确保故事可以被正确地实现,并且满足了所有相关的功能性和非功能性的需求。图3.13-5提供了一个示例。

敏捷团队会尽可能地做到自动化接收测试,通常使用业务可读性、领域专业性的语言编写,由此为系统创建“可自动执行的规范和测试”。自动化也提供了对系统进行快速回归测试的能力,这种能力增强了持续集成、重构和维护。

对好故事进行投资

人们通常会用Bill Wake发明的缩略词“INVEST”来提醒良好的故事应该具备的要素:

I——独立性(Independent,独立于其他所有故事)

N——可协商(Negotiable,灵活的意图表述,不是合同)

V——有价值(Valuable,提供给客户有价值的纵向切片)

E——可估算(Estimable,小的,也是可协商的)

S——小的(Small,适合一次迭代完成)

T——可测试(Testable,充分地理解如何进行测试)

在参考资料[1]和参考资料[2]中,可以得到更多信息。

故事的估算

SAFe中的ScrumXP敏捷团队使用故事点和估算扑克(参考资料[2]和[3]),对其工作进行估算。故事点是一个数字,用于代表以下内容的:

数量——有多少?

复杂度——有多难?

知识——哪些是已知的?

不确定性——哪些是未知的?

故事点是相对的,它们和任何特定的度量单位无关。假定一个最小的故事,给它赋1点,然后其他故事的大小(工作量)可以相对于这个最小的故事进行估算。SAFe应用修改过的斐波那契数列(1,2,3,5,8,13,20,40,100)来体现估算中的不确定性,尤其是对于一些较大的数字(如20,40,100等)(参考资料[2])。

估算扑克

敏捷团队通常使用“估算扑克”,可以综合专家意见、模拟类比、分解等手段来快速可靠地进行估算(也可以使用其他的估算方法)。使用“估算扑克”的规则有:

所有团队成员都参加

发给每个估算者一叠卡片,1,2,3,5,8,13,20,40,100,∞,以及 ?

产品负责人参加会议,但不做估算

Scrum Master参加会议,但不做估算,除非他也参加实际的开发工作

对于每一个需要估算的工作项,产品负责人讲读故事的描述

进行问题的提问和解答

每个估算者独立地选出一张估算卡片,用于代表他的估算

所有的估算卡片同时翻开,所有参与者能看到其他人的估算

给出估算点数最高和最低的人,向其他人进行解释

经过一番讨论,每个估算者使用估算卡片重新进行估算

估算将会倾向于收敛。如果没有,重复以上过程

进行一些前期的设计讨论是适宜的,然而,花费过多的时间用于设计讨论就是浪费精力。估算扑克的真正价值就是对故事的范围达成一致,而且也很有趣!

速度

团队的速度等于一个迭代中完成的所有故事(达到了完成定义)的故事点的总和。了解团队的速度有助于制订计划,也是限制在制品的一个关键因素,因为团队不应该承担超过其速度的过多故事。大型的史诗、能力、特性和使能,都会使用故事点进行估算,所以速度也可以用于估算它们的交付时间。

估算的通用起始基准

在标准的Scrum中,每个团队的故事点估算和速度是局部的、独立的。有可能一个小型团队使用自己的估算方式得到的速度为50,而另一个较大的团队估算出的速度只有12,其实这样的结果对其他团队来讲没有什么参考意义。

然而,在SAFe中,故事点速度必须有一个通用的起始基准,以便于那些需要很多团队支持的特性或史诗可以建立在合理的经济环境中。为了做到这一点,SAFe团队创建了一种方式,使得一个故事点对一个团队和其他团队都有相同的意义。在这样的方式下,伴随着对不同区域经济情况的调整,工作的估算和优先级排序可以基于从故事点到成本的转化来完成。毕竟,如果没有可比性的“通用货币”,就无法确定潜在的投资回报。

对于故事和速度所采取的一种通用的起始基准如下:

对于团队中的每一个开发人员、测试人员,给予8个点(如果非专职成员做适当调整)

每个团队成员休假日和公共假日减1个点

找到一个较小的故事,花费大约半天时间开发、半天时间测试和验证,将其定义为1个点

相对于上述故事,对其他所有的故事进行估算

例如:假设一个6人组成的小团队,包括3个开发人员、2个测试人员和1个产品负责人,他们都没有休假计划,那么就可以估算初始速度= 5人×8点=40点/迭代。(注意:如果开发人员和测试人员中有一人同时担任Scrum Master,则速度可能需要调整得慢一点)。

通过采用这种方法,故事点数在某种程度上可以类比于一个理想开发人日,所有团队都可以用共同的方式进行估算,管理人员就能够为某一特定领域的团队,公平、快速地估算一个故事点所需的成本。然后,他们以有意义的方式为即将实现的特性或史诗建立总成本估算。

注意     在此之后,没有必要校准团队估算或速度,这仅仅是一个共同的起始基准。

虽然团队会随着时间的推移提高其速度,这确实是一件好事,但事实上这个数字往往相当稳定,影响团队速度的更大因素是团队规模、结构和技术背景,而不是生产率的变化。而且,如果有必要,财务规划人员可以稍微调整一下每个故事点的成本。相对于那些在非标准化情况下,大规模团队间大相径庭的速度呈现来说,这种财务调整的影响就显得微不足道了。而且没有通用的起始基准,也就无法进行企业的规模化,因为无法找到决策的经济基础。

故事拆分

颗粒度小的故事可以更快、更可靠地实现,因为小颗粒可以快速地通过系统,减少变异性,易于管理风险。因此,把大颗粒的故事拆分成小颗粒的故事,是每一个敏捷团队的必备生存技能,也是增量式开发的一项艺术和科学。有10种故事拆分的方法(参考资料[1]),以下是这些方法的简要总结:

1.工作流程步骤

2.业务规则变化

3.主要工作量

4.简单/复杂

5.数据的变化

6.数据入口方法

7.延迟系统质量

8.操作(例如:创建、读取、更新、删除或CRUD)

9.用例场景

10.创建一个探针

图3.13-6展示了以上第9项中,通过用例场景拆分故事的示例。

SAFe需求模型中的故事

正如SAFe需求模型所描述的那样,该框架使用了一套完备的工件及其之间的联系,用于在精益和敏捷的环境中定义和测试复杂系统。图3.13-7说明了在大框架中故事的呈现方式。

如图3.13-7所示,故事通常是由特性衍生出来的(有时也有例外,比如团队根据具体情况创建的故事),而且每个故事都与故事接收测试相关联。在极限编程和SAFe的ScrumXP中,每个故事都会有一个单元测试,单元测试的主要作用是确保故事的实现是正确的。此外,因为单元测试容易自动化,所以这是自动化测试的一个关键起始点,可以参考8.2节中的描述。

注意     在图3.13-7中,使用的是UML方式描述对象之间的关系:0对多(0,1),1对多(1..*),1对1(1),等等。

参考资料

[1] Leffingwell, Dean. Agile Software Requirements: Lean Requirements Practices for Teams, Programs, and the Enterprise. Addison-Wesley, 2011, chapter 6.

[2] Cohn, Mike. User Stories Applied: For Agile Software Development. Addison-Wesley, 2004.

《SAFe 4.0参考指南:精益软件与系统工程的规模化敏捷框架》一 3.13 故事相关推荐

  1. 什么是SAFe(规模化敏捷框架)1——全景图基础层

    接下来分几篇文章,简单介绍下什么是SAFe,本文内容是基于SAFe4.0与SAFe5.0 的总结.本篇文章先介绍下SAFe的全景图及基础层. SAFe(Scaled Agile Framework,规 ...

  2. 什么是SAFe(规模化敏捷框架)3——敏捷发布火车(上)

    上一篇我们介绍了SAFe的团队层​​​​​​​,本文介绍SAFe的项目群层--敏捷发布火车,文章内容是基于SAFe4.0与SAFe5.0 的总结. 注:资料来源:分别来自 https://www.sc ...

  3. 什么是SAFe(规模化敏捷框架)3——敏捷发布火车(下)

    注:文章内容是基于SAFe4.0与SAFe5.0 的总结.资料来源:分别来自 https://www.scaledagileframework.com/#,和<SAFe4.0 参考指南> ...

  4. 规模化敏捷框架何从入手?这篇文章把SAFe讲透了!

    摘要:敏捷软件开发理念已渐渐被业界普遍接受,越来越多的公司和团队不得不面对一个新的问题,就是规模化敏捷的引入和实现.目前市场上规模化框架主要有SAFe,Less,Scrum of Scrums, Sp ...

  5. 洞悉规模化敏捷框架 Scrum@Scale 、LeSS 、SAFe (上篇)

    引言 本文以多个维度不同视角向你呈现Scrum@Scale .LeSS 和SAFe三个规模化敏捷框架的共性和各自的特点.包括Scrum团队容器.沟通机制.沟通饱和度.适应性.系统思考.实施路线图.原则 ...

  6. 洞悉规模化敏捷框架S@S、LeSS、SAFe(下篇)

    前面我们分享了<洞悉规模化敏捷框架>上篇和中篇,本篇是文章下篇,将继续从其他维度分析规模化敏捷框架. 点击链接阅读: <洞悉规模化敏捷框架> 上篇 <洞悉规模化敏捷框架& ...

  7. 【Unity 框架】QFramework v1.0 使用指南 介绍篇:01. 简介 | Unity 游戏框架 | Unity 游戏开发 | Unity 独立游戏

    01. 简介 大家好,我是 QFramework 的作者 凉鞋,QFramework 从第一次代码提交到现在快 7 年了(2015 年 12 月 ~ 2022 年 10 月)了,而经过了 7 年时间的 ...

  8. 规模化敏捷框架(SAFe)的原则

    The impression that "our problems are different" is a common disease that afflicts managem ...

  9. 精益软件开发简介之A版

    本简介主要介绍了精益,没有充分说明精益软件开发,本版本也未被选入正式稿,后续相信还将有更好的版本来介绍精益软件开发. 放在这里先睹为快,也是能够快速交付价值. 精益软件开发一词起源于Mary Popp ...

最新文章

  1. numpy 打乱 numpy 数组
  2. 【跃迁之路】【733天】程序员高效学习方法论探索系列(实验阶段490-2019.2.23)...
  3. 2.2. Array
  4. 【知识星球】为什么图像分类任务要从256*256中裁剪出224*224
  5. 第三次学JAVA再学不好就吃翔(part38)--抽象类与接口的区别
  6. android sqlite 备份数据库文件,android – 将SQLite数据库备份和还原到sdcard
  7. magento网站建设_跨境自建站Magento麦进斗代打包代贴单代发货
  8. SQL Server内存架构基础
  9. Unity Camera
  10. mysql event查询_Mysql中Event的一些测试
  11. 希捷低格工具_拯救硬盘问题的终极大招超强电脑硬盘低格工具
  12. PostgreSQL shapefile 导入导出
  13. OPNsense用户手册中文版
  14. numpy dot用法解释
  15. java ipv6校验_IPV6地址校验(java)
  16. a java programe about tcp server
  17. android 自动翻页插件,网页自动翻页Chrome插件下载
  18. 23.卷积神经网络实战-ResNet
  19. 基于babylon.js的3D网页游戏从零教程
  20. linux 命令连接符,Linux 中命令链接操作符的十个最佳实例

热门文章

  1. Shell编程(逻辑判断、文件目录属性判断、if特殊用法、case判断)
  2. 使用meta来刷新网页效果
  3. iOS开发中用到的第三方库概览
  4. Fragment过度动画分析一
  5. Silverlight中使用MVVM(2)
  6. 一起谈.NET技术,HubbleDotNet 和 Lucene.Net 匹配相关度的比较
  7. 详解DMZ的部署与配置:ISA2006系列之二十九
  8. RabbitMq(七) Topic模式介绍及代码示例
  9. WebFlux响应式编程基础之 6 webflux客户端声明式restclient框架开发讲解
  10. go generate介绍及使用