探寻本源,用户故事为什么被敏捷推崇

引言

用户故事是敏捷开发中不可或缺的一环,也是BA工作中绕不过去的一环。

在以往工作的经历中,对于如何评价一个BA的卡是否写得好,常常听到大家的标准是AC细节是否滴水不漏,大家更愿意将AC等同于「卡」来进行细节的争论,却鲜少争论「故事」本身。

这让我在入职初期边吭吭哧哧花很多时间写细致到标点符号和点击按钮跳转的AC,又一直有一个迷思:这么写跟一张小型需求文档有啥区别呢?我都写成这样了,测试用例还要写啥啊?我都写成这样了,怎么还能在DC的时候才告诉我这个技术上无法实现啊?白纸黑字到底哪里出了错!

在复杂业务下,它的格式能承载的信息又不够描述清楚上下文,我还得依托其他的流程图等等工具辅助在卡里说明,那描述和传递需求的方式有这么多种,用户故事为什么被敏捷推崇?

我想纠结一个实践本身的标准实际并没有意义,所有的实践都是为了解决某个问题而存在,因此这篇文章想通过向上思考为什么敏捷要用用户故事来聊聊它的本质和价值,以便我们可以更好地应用用户故事。

Why 用户故事

最初的问题

用户故事的起源可以追溯到20世纪90年代,当时软件开发界还在流行瀑布式开发,整个开发周期采用需求→开发→测试按部就班的线性模式进行协作,导致普遍存在以下几种问题:

  • 不同角色之间的交流和沟通相对较少,极易在不同阶段出现需求理解偏差,导致最后的产出不符合预期。
  • 线性协作的流转周期较长导致问题的发现有严重的滞后性,大大增加了修正错误的成本。
  • 由于团队以整个需求文档为指导来进行开发,因此很难及时响应需求变化。

极限编程 - 用户故事的诞生

Ron Jeffries、Kent Beck和Alistair Cockburn等人就是在这样的背景下提出了极限编程(XP)的软件开发实践,也在21世纪初和其他几个志同道合的人一起喊出了敏捷宣言。

极限编程里所推崇的实践大部分和我们现在所熟知的敏捷实践一样,它的目的就是为了解决如上所述传统软件开发中的问题,从而让软件开发可以达到:

  • 能快速发现和响应业务变化;
  • 能持续优先交付高价值/高质量的软件。

在此目的下,XP推崇以团队紧密协作、尽可能短的反馈循环以及卓越技术的原则来指导采取的实践,譬如站会是为了团队可以及时暴露风险和寻求帮助,开/结卡、按迭代进行开发和showcase等都是为了缩短功能的验证周期,code review 、重构等都是为了追求技术卓越。

显然,敏捷开发如果继续使用冗长、复杂,难以理解和快速验证的传统需求文档来进行迭代开发已经无法满足这样的实践原则:

  • 需求文档写出来之后业务不会一成不变:如果在—开始的时候就花费大量的时间来完善整个方案的功能细节,然后以此来指导开发,不管是由于业务变更造成的文档修改还是代码修改都是对人力的极大浪费。

  • 即使需求的细节写得再详细,文档也无法把所有隐含的业务知识百分之百传递出去 :由于每个人的知识体系不一样,同样的表达不可避免地会在表达者和接收者之间造就不同的理解,既然不可能有完美的表达,那么相比详尽的文档,用促进沟通代替阅读更能不断交换彼此的隐性知识,达成对业务价值的共识;

  • 继续使用整体功能文档的粒度来指导团队进行开发,无法实现迭代开发的需求管理和验证反馈:人力和时间都是有限的,并且并不完全可控,而一个解决方案里,不同的功能并不是都在同一个不可分割的优先级,我们需要一个办法始终让优先级最高的功能点先被交付,进行验证。

因此,为了实现开发「敏捷化」,需求也同样的需要「敏捷化」,在团队交付最终软件之前需求都应该可以被快速简单的迭代,由此用户故事在极限编程方法的实践中应运而生,并逐渐演练成敏捷开发方法的核心概念之一。

所以用户故事是?

大道至简,回归本源,用户故事名如其意,最开始的初衷就是期望用故事的方式讲述需求,核心的思想就只有三句话:

通过As a user role,I’d like to …, so that …的形式来强调什么用户、需要什么功能和为什么需要这个功能(能得到什么收益),其中用户想解决的问题是故事的核心,满足需求的功能方案可围绕目标进行协商。

所以,它首先是一个需求的沟通工具:

在需求早期的时候可以和利益相关者们快速地通过先写出一个起始的目标层面及占位意义的故事列出业务想要解决的问题,让大家对要开发的系统有一个整体的概念,然后始终围绕业务目标来思考需求存在的必要性;

进入迭代后,这种场景化描述易于理解和记忆,可以将业务价值清晰传递给团队,团队可以将注意力从纠结功能如何做转向从理解和讨论用户故事的sothat开始来对验收的标准达成共识,朝着清晰的目标前进。

要知道当一个人对于正在做的事不知道有何意义时,是痛苦的。BA需要不断跟团队拉齐业务的目标感,这样团队才不会后劲不足。

###其次是一个需求的管理工具:

通过user以及so that不断追问业务价值,用户故事可以将大的业务目标逐步拆解成一个个小的目标,从而选择出ROI最高的解决方案,保证团队可以始终优先交付业务价值最高的功能最小集;

同时用户故事的编写和管理更加灵活,可以快速进行拆解和优先级排序,适应需求的变化。

How to use it - 一些小tips

在理解了用户故事在敏捷中的本质之后,我结合过往的项目经历,重新思考总结了我认为非常有用的两个用户故事的使用方法,

怎么拆卡:时刻谨记so that大法,切勿从功能出发

我们可能常常会面临很多「伪」敏捷场景,比如需要在很早期的阶段就开始评审总体方案和高保真原型,或者在进入迭代前需要跟客户sign off故事卡,很多时候我们就会不自觉陷入如何让客户buy in解决方案的思维陷阱中去,也就是先把方案做出来了,再在方案的基础上开始写story。

这个时候,因为下意识觉得方案已经定了,原型也出来了,BA往往就会不自觉倾向于拉着TL从「开发角度」下的工作量大小和开发依赖出发功能by功能地进行拆卡,而不是渐进增强地按照最小业务价值去拆卡。

by功能拆卡和by价值拆卡两者的区别是什么呢?我举一个项目上非常简单的真实例子:

产品背景:一个白板协作工具,核心产品场景是聚焦于团队的工作坊协作而非个人作图工具,核心用户是工作坊facilitator,白板是facilitator收集参与者想法的承载工具。facilitator可以引导参与者使用数据sticky来表达想法,数据sticky的文字内容及其对应的标签会被自动收集到数据表中供facilitator整理产出。
需求背景:facilitator在准备工作坊白板的时候有信息传递需要,但这部分信息并不是协作产出,被数据表收集反而会污染产出数据,因此,产品需要提供给用户纯视觉的图形文字功能进行信息区分。
这是一个任何可以绘图的工具里都非常常见的一个功能,并且设计大同小异。以下是设计图稿:
截屏2023-06-08 15.44.59.png
按功能拆卡:
story 1.在图形上添加文字
AC 1 白板协作者可以直接在图形上编辑文字,保存后的文字会显示在图形上(不溢出)
AC 2 白板协作者在图形上编辑文字时超出了图形范围,超出的部分会半透明显示
AC 3 白板协作者保存文字后,超出图形范围的文字部分会被图形遮挡,并且有「展开」按钮(溢出)
AC 4 存在文字溢出时,白板协作者可以展开图形让文字显示完整(溢出)

但从问题出发去阐述这些功能提供给用户的益处,就会发现这里面实际上混杂了好几种不同的用户价值:
Story 1.用户可以在白板上使用非数据图形元素来传递信息 – 验收点:in scope :可以编辑文字,溢出后被遮挡;out scope :展开按钮;
story 2.用户可以一键让图形自适应文字篇幅无需手动拉伸 - 验收点:溢出时有展开按钮告知用户可以展开,能够将图形展开到可以显示所有文字;
story 3.用户在编辑的时候就可以明显区分哪些文字会被遮挡 - 验收点:溢出时有展开按钮告知用户可以展开,能够将图形展开到可以显示所有文字;

可以很明显地看出来,卡1其实就实现了用户的核心诉求,并且已有的功能也可以曲线解决卡2和卡3想要解决的问题:1.被遮挡后用户可以自行去拉伸图形适应文字,只是卡2提供的是体验更好的快捷操作;2.即使不区分透明度,用户只要保存一次也能知道这部分已经溢出了;
产品的核心场景和persona,可以轻松判断业务优先级story 1>>story 2>>story 3;再加上story 3评估之后实际需要花费的effort远超出了它的收益,因此story 3一直放在产品backlog里没有被规划进迭代。

上面的例子里,最开始我们就是按照功能拆的卡,开发估点的时候也没啥意见:从功能来说,就是这么设计的嘛。然后开发开始闷头干活,直到干到透明度的时候才发现发现卧槽,这个实现好像还有点复杂,活好像干不完了才想起来和BA讨论scope有点大啊;

放在客户项目的场景里,就是一来时间就这样被浪费在了一个优先级非常低的功能点上。二来卡拆出来还又得和客户去说明为什么这个我们说好的功能点这个迭代做不了。

这并不能怪开发在估点和开卡的时候没有认真思考提前告知,就像BA写需求文档一样,开发也无法在开始编码前就知道所有的实现细节。

所以对于BA来说,在进入复杂度和依赖的讨论前,我们需要的就是将故事卡拆解为一个个业务最小价值,不用在乎卡会不会太小,会不会太多,在此刻,最重要的是把问题讲清楚,边界讲清楚,优先级讲清楚。

要知道,需求并不存在膨胀一说,只存在价值不明晰而导致的边界不清晰。故事的边界清晰了,我们跟客户对迭代scope进行圈定的时候,对业务优先级的共识也会更明确,少一些showcase时和客户掰扯「这个功能点怎么没做」的场景。

不过需要注意的是,最小代价实现功能也不代表着要放弃所有的用户体验和产品设计一致性,一个业务价值应该被拆至何种粒度,满足这个价值的功能范围可以被舍弃到哪种程度,就需要BA结合当前的产品阶段定位和资源情况,不断去进行刻意练习了。

怎么写 : 鼓励沟通,别把AC写成测试用例

同样的,一个故事卡进入迭代之后,也会常有一个思维误区:既然方案都已经和客户确认了,那BA应该致力于把方案细节尽可能写清楚以便减少澄清AC的浪费。

所以BA经常会花费大量时间在写卡(尤其是写AC上),但大家回忆一下,是否不管你花多少时间去写卡,不管这个BA有多么公认的好能力,也不可能做到ta所有的卡开卡无补充和错误,开发过程中无开发再来澄清,DC的时候实现还和业务脑袋里的要求一模一样无争论。

这并不能归结到是谁的能力有问题,只是这种期待把故事卡写成小型需求文档的方式完全背离了用户故事的初衷,这种情况下,开发拿到卡之后依然会先去专注于如何实现AC中的具体步骤和结果,忽略了本应最重要的用户需求和期望。

再重复一遍,用户故事被推崇的假设之一就是文档无法百分百传递所有的隐含知识,而BA也无法同时没必要花太多时间写出跟测试用例一样详尽的功能交互细节。

因此,最占大头的验收条件部分,实际上是最不应该占据BA精力的一部分,BA应该把起码百分之50以上的精力放在业务的价值分析和验证上。

当前期的业务问题和persona都分析好了,solution的优先级层级拆清楚了,那么一张可以放进迭代的、业务价值明确的故事卡,BA需要写的验收标准的粒度也应该只止步于帮助团队和利益相关者对于功能的期望达成场景和范围的共识,而不是具体的实现细节。

至于客户项目中客观存在的诸如开发需要什么样的粒度来进行复杂度估算/客户需要以故事卡详细的验收标准为依据进行生产的回归验收等等问题,BA可以根据具体的项目情况,和QA/开发磨合一套稳定的协作节奏,在适当的时机和QA or 开发一起pair将细节补充完整(毕竟QA得写测试用例,开发得拆task写测试嘛不是);

比如如果你的项目需要跟客户签卡才能进迭代,那就尽早开始和团队产生沟通,在签卡前先拉齐团队认知,共同对需求达成一致,将卡pair写好。

结语

最后借用不知道从哪看来的一句话:敏捷无定式,最重要的是它的思想。

希望我们都能不断深入理解对自己所做的事情的意义,永远以目标为导向使用手段,而不被标准所束缚。

尼采在《偶像的黄昏》里说:If you have your why for life, you can get by with almost any how. 生活如此,工作也如此。

参考资料
《用户故事地图》:作者:Jeff Patton

《用户故事和敏捷方法》:作者:Mike Cohn
《极限编程》:作者:Kent Beck等人


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 350394277@qq.com

Title:探寻本源,用户故事为什么被敏捷推崇

Count:4.3k

Author:Yunlong Wen

Created At:2023-12-17, 14:18:27

Updated At:2023-12-17, 14:18:27

×

donation.headline