5.1 敏捷分析
敏捷分析(Agile Analytics)是一种开发风格,在它的指导下,用户、利益相关者以及开发者在整个开发周期中共同协作,尽早且持续不断地传递商业价值,构建一个高品质、可用的数据仓库(Data Warehousing)与商业智能(Business Intelligence)系统。
类似于敏捷软件开发(Agile Software Development),敏捷分析建立在一系列简单的核心价值及指导原则上,它不是一个死板固定的方法,但需要高度训练及严谨正确地执行。可以说这是一种介于完整结构与灵活性之间的开发风格,区别于没有结构或者过于僵化的过程。在进一步分析敏捷分析的特征之前,首先需要对关于敏捷的几个常见误解进行说明。
5.1.1 几个常见误解
敏捷意味着更快地完成项目
在敏捷的指导下,快速完成项目是可能的,但这不是敏捷的首要目标,敏捷追求的应该是传递商业价值,提高项目质量和成功率。
敏捷只是少部分人的事
敏捷绝不只是少部分人的事,一次卓越的敏捷实践,必须集合所有团队成员的努力,从思维上到行动上都朝着敏捷转变。
敏捷就是简短且经常性的迭代开发周期
敏捷给人直观的感受之一,就是简短且经常性的迭代开发周期,一般一到三周就是敏捷的一个迭代开发周期,这也是敏捷的重要基石之一。但这不意味着只要迭代开发周期短就是敏捷了,敏捷要求每个迭代都能产生一个可演示的可用软件,以尽早展示可用功能并从用户那频繁地获取反馈。
敏捷不需要严谨和确保质量
敏捷简单但不容易,它必须在遵循其核心价值及指导原则的前提下,被严谨正确地执行,确保交付高价值、高质量、可用的软件。
5.1.2 敏捷分析特征
正如前文所述,敏捷分析是一种开发风格,其首要目标是构建一个高价值、高质量、可用的商业智能和数据仓库系统。为了实现这个目标,敏捷分析需要具备如下的特征:
- 迭代、增量、进化:敏捷通过不断适应用户的频繁反馈和持续地进行短期迭代,逐步发展为可用的系统。我们可以将构建DW/BI系统的过程视为在陌生海域的一次航行,在没有确认方向正确、航线畅通的情况下,需求借助与用户频繁的短期交互,来确保没有偏离正确的方向太远。
- 价值驱动:在上一节提到,敏捷要求每个迭代都能产生一个可演示的可用软件,这是为了确保每个迭代都能产生一个具备用户价值的功能,以帮助用户解决问题。
- 产品质量:每个功能都必须确保其质量,以确保向用户传递正确的价值。
- 刚刚好的过程:敏捷的最主要目标是高价值、高质量、可用的系统,为了达到这个目标,必须确保质量,但构建这个系统的过程却可以一切从简,不需要每一步都完美无缺,只需刚刚好。
- 自动化:真正的敏捷需要尽可能地自动化处理日常流程,已更加专注于开发高价值的功能。
- 协作:用户、利益相关者以及开发者的紧密协作是敏捷项目成功的关键。
- 自我驱动:最大程度地发挥团队成员的主观能动性。
5.1.3 敏捷分析开发宣言
在2001年,一群伟大的开发者发布了敏捷软件开发宣言,它为敏捷的实践提供了依据,为了让宣言更适用于敏捷分析, Ken Collier 对它进行了一些调整:
我们一直在实践中探寻更好的软件开发方法,身体力行的同时也帮助他人。由此我们建立了如下价值观:
- 个体和互动 高于 流程和工具
- 可用的数据仓库和商业智能系统 高于 详尽的文档
- 终端用户和利益相关者协作 高于 合同谈判
- 响应变化 高于 遵循计划
也就是说,尽管右项有其价值,我们更重视左项的价值。
5.2 用户故事
在构建数据仓库和商业智能系统(下面简称DW/BI系统)时,开发者们总是会以数据为中心,首先从数据层面上进行大量的工作,他们甚至错误的认为,只要确保数据的正确,就可以满足未来一切可能的用户需求。但实际上,这样的DW/BI系统往往不能很好地解决具体的商业问题,因为这类系统并不是建构在对用户需求的了解上,也没有尽早地向用户传递商业价值,以至被用户所抛弃。
而敏捷分析强调的是价值驱动,在整个开发的过程中,开发者迫切地期望开发出能满足用户需求、解决商业问题的可用功能,数据只是服务于这个目标。因此,敏捷分析的第一步应当是广泛而快速地收集用户需求,并加以组织,然后将其转化为确实需要开发的高价值功能。要做到这点,就需要使用到敏捷开发中的用户故事(User Story)。可以说,敏捷分析是以用户故事驱动的方法来构建DW/BI系统,而非数据驱动。
5.2.1 用户故事概述
用户故事被广泛地运用在敏捷开发的过程中,它是对需求的细化和切分。通过用户故事,可以快速地收集并组织项目需求,而无需在前期进行广泛而深入的需求分析,并在之后将需求具体化成可以进行迭代开发的一个个现实的可见的开发任务。可以这样理解用户故事:
一件用户通过系统实现他的一个有价值的目标的事,就是一个用户故事,即从用户角度进行描述的故事。
5.2.2 用户故事内容
用户故事通常按照如下的格式来表达:
作为一个<角色>,我需要系统能够<做某事>,这样我可以<目标陈述>。
举例如下:
作为一个产品运营人员,我希望系统能够让我看到新登用户中只有一次会话的用户(DOSU: Daily One Session Users),这样我可以衡量新用户的质量。
当然,用户故事也可以按照如下的格式来表达:
为了实现<目标陈述>,作为一个<角色>,我需要系统能够<做某事>。
在这两个模板中,都包含有3个要素:
- Who:用户角色。
- What:通过系统完成的某项操作。
- Why(reason):需要达成的某个目标(实现的商业价值)。
需要注意,用户故事不需要使用技术语言来描述,而是以用户可以理解的业务语言来描述。另外要避免用户故事的内容过于复杂,例如下面这个反面案例:
作为一个产品运营人员,我希望系统能够让我了解每一个用户的留存成本,这和平台的盈利相关。我还需要按照性别、年龄层、收入水平来分析用户特征,这样我可以发现降低成本或者增加例如的机会。
5.2.3 编写优秀的故事
一个优秀的用户故事需要具备如下特点:
- 它可以代表客户群体的商业价值。
- 能够实现为可用的功能演示给商业用户,以便收集他们的反馈。
- 能在单个迭代期内完成,成为架构完整(architecturally complete)且达到上线质量(production-quality)的可用功能。
上节的反例就没有做到第三点,它过于复杂,难以在单个迭代期内完成,需要将其分解为多个更简单且符合上述3个特点的用户故事。这里我们还要再了解一个经常与用户故事一起出现的概念——史诗故事(Epic),通俗来说就是大型故事。Epic由许多较大的不确定的需求(large fuzzy requirements)组成,而且经常混杂了许多不同的特性(一个特性就是一组可以归为一类的需求),不能直接通过其完成迭代和开发。因此,我们首先需要将史诗故事划分成较小的真正的用户故事,然后才能组织用户故事进行迭代开发。
在编写一个优秀的用户故事时,需要遵循INVEST原则:
- Independent:独立性
用户故事之间应该具有独立性,不应该依赖于其他的用户故事。否则将会导致用户故事之间存在着不同的优先级,只有被依赖的用户故事完成才能继续开发依赖的用户故事。一般可以通过对用户故事的组合或分割来减少相互依赖性。
- Negotiable:可协商
用户故事不是签订的商业合同,它是由客户或者PO同开发小组的成员共同协商制定的,因此它不需要太多的条条框框,以保证更好的沟通及协商。
- Valuable:有价值
用户故事必须对于终端用户是有价值的,因此应该站在用户的角度去编写,描述的是 feature,而非 task。
- Estimable:可评估
用户故事的划分要保证其可以被很好地评估,以减少估算的不确定性。
- Small:短小
故事应当尽量的短小,最好是能够在一个迭代周期之内完成的,如果太大就应该考虑将其拆分为多个更细颗粒度的故事。
- Testable:可测试
用户故事必须是可测试的,否则无法判断该故事是否被完成,另外测试的过程做好可以实现自动化。
关于用户故事,还有一个很经典的由 Ron Jeffries 提出的 3C 原则:
- Card(卡片):用户故事一般写在小的记事卡片上,除了故事本身的描述之外,还应该包括故事的时间点估计及对应的测试行为等等。
- Conversation(交谈):用户故事背后的细节需要项目组中的成员与PO或者客户之间沟通得出的。
- Confirmation(确认):通过验收测试确认用户故事被正确完成。
5.2.4 用户故事是需求的代表
用户故事本身不是需求,而是需求的代表,它帮助项目组快速收集并组织需求,并通过讨论和协商确定系统需要支持的性能和功能,而无需在一开始就在详细的需求分析和设计中花去大量的精力。正如 Mike Cohn 所说,用户故事“确保了大家能够对用户需求进行对话交流”。而 Scott Ambler 在一次开发BI系统的过程中发现,通过和用户协作撰写用户故事,可以在几天内便收集到所有需求的 80%。
5.3 敏捷分析中的用户故事
下面将会通过一个虚构的例子,展示如何在敏捷分析开发的过程中运用用户故事。
5.3.1 识别用户角色
有一家名为富贵便利店的连锁便利店公司,需要搭建一套 DW/BI 应用,以满足其内部多个部门对数据的商业需求。在这种情况下,首先需要识别不同用户角色,以便对照着这些用户角色来撰写用户故事,而不至于偏离方向。在识别用户角色的过程中,需要注意以下两点:
- 在一段时间内,同一个人可能兼任不同的用户角色,例如财务总监在整个商业过程中扮演了很多不同的角色。
- 当用户的目标发生变化时,也可以修改用户角色。
通过头脑风暴收集第一批用户角色,并将用户角色列出来:
接着,按职能的相似程度进行分组,将职能上有重叠的两个角色重叠放置:
最后,将重叠度高的角色进行归纳,再通过定义差异特征、预期使用频率、使用模式、数据分析能力、领域专业度、使用目标以及其他因素来完善用户角色,并用一段简短、描述性的话将这些信息写在用户角色卡片上:
为每个定义好的用户角色创建一个具体的用户形象,有助于团队持续地具象思考他们的用户是谁、需要什么样的功能、实现什么目标。
5.3.2 用例建模
现在,已经建立了一系列的用户角色,要在此基础上撰写一整套的用户故事,这工作似乎有点庞大。不要紧,还可以通过用例建模,将问题逐步分解。用例建模的第一步就是创建一张用例图:
下一步是定义用例图中每个用例的细节:
一个简单的用例可以直接写成用户故事,例如“登录 BI 应用”这个用例就可以简单地写成一则用户故事:
作为一名盈利能力分析员,我希望系统能让我登录到 BI 应用上。
但大部分情况下,用例细节中都包含了若干用户故事,需要在用例细节中的主事件流找到这些用户故事,并将其拆分出来。
5.3.3 拆分用户故事
在前文反复提到,一个优秀的用户故事应当是能在一个迭代期内完成的,但不可避免地会遇到中篇、长篇甚至超长篇(史诗)的用户故事。这类故事与用例接近,它们描述的功能反映了各种事件流和场景,常包含多个不同的故事,或单个复杂的故事。必须将这类故事拆分为更加短小、简单的用户故事,以确保能在一个迭代期内完成用户故事。
下面举两个例子:
作为一名销售预测人员,我需要系统能够让我了解每家店的日常收益、每天的成交笔数、每家店附近的顾客在人口统计学上的特征、过去两年每家店的历史收益,这样我才能分析并且预测收益和购买的趋势。
这是一个典型的包含了多个用户故事的集合,实际上,该故事表达的是:
作为一名销售预测人员,我需要系统提供以下几个功能:
- 了解每家店的日常收入。
- 了解每天(或每家店)的成交笔数。
- 了解每家店附近的顾客在人口统计学上的特征。
- 了解过去两年每家店的历史收益。
再看另外一个例子:
作为一名财务预测人员,我需要系统能够让我了解前 10% 的客户中,每个客户在每笔交易中的利润和利润率,这样我就能找到最具盈利能力的交易具备哪些特征。
这个用户故事看似合理,却包含了相对复杂的需求,暂时去除 “前10%“ 和 ”利润率“ 两部分,才是一个简单、短小的用户故事。
为了让每个迭代期都能向用户交付架构完整且达到上线质量的功能,需要确保用户故事足够简单、短小,这也意味着这些用户故事不够成熟,可能需要几个成功的迭代期来不断完善。
5.3.4 故事优先级
用户故事放在设定好优先级的产品待办事项列表上进行管理。用户故事评定优先级与其他敏捷行为一样,也是一个逐步递增和迭代的过程,一开始可以比较粗略,然后再逐步深入细节来加以区分。评定优先级的方法通常有两种:
(1)基于价值评定优先级
敏捷分析的目标是持续不断地为客户/用户交付高价值、高质量、可用的软件,这使得评定优先级的首要考虑因素便是价值,但同时还要考虑开发成本和风险,因此一个基于价值的优先级评定模型应如下:
- 首先完成高价值、高风险的故事(如果它们的开发成本合理)。
- 接着完成高价值、低风险的故事(如果它们的开发成本合理)。
- 最后完成低价值、低风险的故事。
- 舍弃低价值、高风险的故事。
(2)基于主题或功能评定优先级
当项目包含数量庞大的用户故事时,按主题或功能进行分组,可以区分不同组用户故事的优先级,同时可以通过发布周期的主题,将非相关的用户故事评定为较低的优先级,保证属于该主题或功能用户故事被优先开发。
5.3.5 待办事项管理
在为用户故事放入待办事项列表并评定好优先级后,需要对其进行持续地维护和管理。按从高到低的顺序将用户故事排入迭代期内进行开发,对完成并通过验收测试的用户故事打上标签并归档。若在开发期间出现新的需求信息,那么优先级和对用户故事的理解都有可能过时或发生变化,需要及时加以调整,保持待办事项对用户故事的最新理解和新的优先级的体现。
5.4 小结
敏捷分析开发相较于传统的 DW/BI 开发方式,更加关注尽早且持续地交付给用户高价值、高质量、可用的功能,关注用户以及他们想要做什么的用户故事。因此,在敏捷分析开发过程中,使用用户故事替代传统的功能性需求分析,正如本章第3节所展示的那样,通过识别用户角色、用例建模、梳理用户故事逐步完善更多细节,并保证用户故事的撰写符合 INVEST 原则,足够短小、简单,能在单个迭代期内完成,然后设置故事优先级和管理待办事项。