作者|李想故事卡要尽量简洁,不要什么都写得详细;同时,它们应尽可能完整和准确,而不是缺乏细节和模棱两可。这是我的基本观点,我的考虑如下:简洁是指读者获得的信息是精炼的,读者可以更有效率地阅读。简洁意味着BA可以更高效地写卡片,将更多的精力投入到其他更具挑战性的工作中。完整和准确意味着故事卡经过讨论并达成一致。完整准确意味着故事卡有明确的验收标准。完整准确意味着故事卡易于追踪和转移。……基于以上观点,我们将分门别类地进行讨论。页面交互说明上图为添加新账号功能的UI设计。对该功能需求的描述可以是:用户通过主菜单进入“权限管理”模块,选择“账户管理”标签页,可以看到“添加账户”按钮。点击“添加账号”按钮,系统会弹出一个添加账号的窗口(可能还有一句“设置背景为灰色”)。用户可以在窗口中填写姓名和登录邮箱...如果用户没有填写必填项,点击“确认”时会给出错误提示“请填写所有必填项!”点击“确认”按钮后,会弹出两次确认窗口,二次确认信息为“确认创建此账户?一旦账户创建成功,将通过邮件通知相应用户”。如果用户再次选择“确认”,系统将创建一个账户,如果用户选择“取消”,则返回到填写账户的窗口。这些文字描述没有错误,应该能满足很多Dev同学或者QA同学的胃口,但在我看来过于臃肿。试着思考简化哪些信息不会影响Dev编码和每个角色对业务的理解:(1)是否需要详细描述操作步骤?通常是不必要的。一般来说,设计图或简单的沟通很容易表达这些内容。主要路径可以在故事卡中简单表达。详细的描述约束了设计和实现,使故事卡片臃肿。(2)是否需要描述所有字段?通常是必须的,但是应该从业务的角度来描述,后面会详细讲到。(3)是否需要详细描述用户操作后的系统反馈?通常没有必要,因为绝大多数系统反馈都是常规的或显而易见的。例如,弹窗下方的页面变灰,点击弹窗上的“取消”按钮后,弹窗将关闭等。那么什么是“异常”情况呢?通常期望系统根据业务目标提供反馈。比如我会提示“创建用户成功后页面应该跳回列表页”,因为我知道管理员通常会批量创建多个用户,效率更高。(4)是否需要在二次确认功能中详细描述文案?很多时候是需要的,因为这些文案通常是想表达一个特定的业务意义,而把这个层次的业务意义用完美的文案表达出来是BA的职责。反过来的情况呢?比如一些例行的删除操作的确认副本就不需要一一描述了。可与团队约定,所有删除操作均需二次确认,二次确认副本均为“确认删除xx?删除后不可恢复”,如有特殊情况另行说明。所以对于上面的需求,我的描述会是这样的:权限管理员可以新建用户:(1)路径:后台管理端-权限管理-账户管理-“添加账户”按钮(2)添加账户必填字段name...Loginemail...(3)Confirmation需要确认两次才能创建账户,文案“Confirmtocreatethisaccount?一旦账户创建成功,将通过邮件通知相应的用户”Briefsummary,在我看来,故事卡片一般不应该过多描述页面交互,这可能会束缚设计和实现,故事卡片也容易失去业务重心。但如果一个想要的交互是独一无二的,或者交互本身就是一个重要的接受点,那么也需要简洁准确地表达出来。关于业务逻辑的描述,这里的业务逻辑可以狭义的理解为功能需求中的规律或者规则,也就是我认为的“如果有,一定要在故事卡中体现”。我的理由是:它们通常适用于特定的业务场景,不能通过一般认知推导出来。它们通常是核心,直接决定需求能否达到预期收益。它们通常很复杂且难以记住。所以我们可以直接讨论如何简洁准确地描述这些规则。我曾经处理过预定交货的需求。背景是客户购买“我们”的产品,物流承运商负责将货物运送到客户的仓库。然而,客户的仓库往往没有可用的存储空间,导致承运人将货物送到仓库,却无法将货物卸入仓库。解决方案是在客户端开发预留存储空间的功能,并提供接口。我们调用这个接口来告诉客户的系统预期的交货信息。客户系统对应预留仓位,反馈预计发货时间。承运人确认后按时间发货。商品。这种业务场景的特点是每个节点都有多个不确定性,对后续流程的影响不同。在业务已经梳理清楚的前提下,这其实是一个如何表达结构化信息的问题。先试试GivenWhenThen的表达式:AC01Thereservationdateiswithinthewindowrange当客户系统返回“在预订窗口范围内”的预订日期时,则通过邮件通知承运人进行确认,预订订单状态改为“待承运人确认”AC02预约日期在窗口范围外当客户系统返回“不在预约窗口范围内”的预约日期时,且该预约日期未被人工确认。然后,将通过电子邮件通知销售负责人进行协调,并将预约订单的状态更改为“待销售确认”。AC03预约日期已过人工确认WHEN客户系统返回“不在预约窗口内”但标记为“人工确认”的预约日期。……似乎每一个细节都能表达清楚,但可读性比较差,读者可能需要额外的努力来理清场景之间的逻辑关系。然后试试“BA风格”的伪代码:“如果客户系统反馈的预约日期是在约定的时限内获取的{如果日期在预约窗口内,将通过邮件通知承运人确认,并且预订订单的状态将更改为“待承运人确认”;否则,如果已手动确认日期且预约成功,则将预订订单的状态更改为“预订已完成”,否则通过电子邮件发送给销售负责人协调处理,将预约订单的状态改为“待销售确认”}else...”逻辑关系表达的很清楚,但是阅读大篇幅充满逻辑的文字体验还是不行好吧,好像可以更简洁一点。最后我用一个状态转换图描述了这些规则,然后跟Dev和QA同学交流这个图是否可以作为验收条件。跟他们解释完这张图后,大家觉得只要对图中每个节点的业务意义达成一致,约定好Scope(而且这些都比较容易),这样的表述会更清晰,更友好,所以我们很高兴地接受了这种方式。简单概括一下,在我看来,业务逻辑的表达是写故事卡的重点和难点。BA要根据项目和需求特点选择最佳的表达形式,不要拘泥于一种固定的形式。图表通常是不错的选择。图表的使用有以下提示可供参考:复杂的条件组合产生不同的系统行为(如积分判断规则)>决策表、决策树或事件-响应表复杂的状态规则(如订单状态规则)>状态流程图或状态表复杂的业务流程(例如采购流程)>业务流程图...另外,团队需要就如何理解这些新表达方式达成一致。关于列表和表格的描述列表和表格是最常见和最基本的需求,可以通过应用固定的模式来表达清楚。列表式需求的共同要素:功能权限:在什么情况下谁可以使用表单数据权限:数据范围的控制通常体现在列表中,比如用户只能看到所有者是自己的订单记录.排序规则:列表中的记录通常需要按照一定的规则进行排序,以便查看分页规则:如果某些列表中没有太多可预测的记录,则不一定需要分页,Dev可以处理这样的列表更简单。字段列表:列表中所有字段的说明。这部分内容会体现在UX设计图中,但经验表明这并不容易,也不需要及时反馈设计图中字段的变化。在某些情况下,设计图不能反映所有领域。字段属性:字段对应的业务含义,告诉读者这个字段的值从何而来,如果某个字段有特殊的规则,也可以在这里体现。比如[Duration]字段是为了方便用户查看,实际上并不对应数据库字段,所以这里它的取值规则可以描述为“[当前时间]-[开始时间],占用一整天”;又如【店名】通常很长但很重要,我将其描述为“当鼠标悬停在【店名】上时,可以查看其完整信息”。清单受理条件参考如下:AC01查看发票清单:(1)路径:主菜单>发票清单(2)功能权限:权限管理中新增“查看发票”权限,仅拥有此权限的用户可以看到“发票列表”菜单和访问列表数据(3)数据权限:承运人用户只能查看他负责的发票,销售用户只能查看他负责的客户的发票,其他角色可以看到所有发票(4)排序规则:按照发票创建时间倒序排序(5)分页规则:每页15个(6)字段详情和顺序【发票创建时间】系统接收到承运人的TMS系统发票送达时间,精确到分钟[发票编号]承运商TMS系统的发票编号[门店订单号]发票对应的门店订单号[门店名称]发票对应的收据门店名称,鼠标悬停查看t全称...关于表单类功能需求表单通常用于创建记录、更新记录、查看记录的详细信息。与列表式需求中字段属性的描述相比,需要注意以下几点:是否必要。数据类型:比如时间类型字段,前端同学会把它当成日期时间选择器。验证规则:例如验证用户名的格式或密码的复杂性。如果是picklist,option是什么:option可能是一些枚举值,也可能是来自另一个业务实体(比如为一个订单选择一个客户),这个需要详细说明。CharacterLength:从业务角度提供字段长度建议。所以一个表格的描述可能是这样的:(1)...(2)字段详细信息和顺序【姓名】必填,50个字符【出生日期】必填,日期类型【省份】必填,单选,从基础数据区域表中取值【城市】必填,单选,从基础数据区域表中取值,与【省份】挂钩【家庭成员数】必填,正整数【联系邮箱】选填,100character,verifyitastheemailformat...还有几个问题可以在这里讨论:(1)对于[ContactEmail]字段,通常会有email格式的验证。那么BA是否需要在故事卡中详细描述验证规则呢?我的建议是没有必要。因为邮箱格式验证是一个“普遍约定”的规则,不具有独特的商业价值,不应该因为BA的不同表述而有所不同。所以这种问题可以交给Dev同学。(2)是否需要以及如何描述字符长度/取值范围?我的建议是可以描述。以字符长度为例,大部分字段其实都比较容易推断出字符长度,比如“订单状态”,10个字符就够了,Dev和BA通常从各自的角度来看偏差不大。既然如此,BA写出来就好了,更何况在特定的业务场景下,某些字段可能会有特殊的要求。可能还有其他问题可以进一步讨论,但总而言之,列表和表单需求通常可以复用一套模板,再结合业务场景调整即可。关于接口的描述,我个人最喜欢的是接口类的故事。没有别的,但很简单。对于接口类需求,我通常的做法是:BA在接口业务上定义数据结构,业务主键和Dev线下讨论达成一致,Dev补充技术细节形成接口文档,将接口文档附在story上卡片、补充业务场景、调用频率(针对主动拉取数据的接口)、错误处理机制(如提交订单失败后是否立即重试或报错)、对接口获取/提供信息的特殊处理(如作为来自外部系统的订单,我们必须按照我们自己的规则生成新的订单号)和其他必要的信息。最后,对用户故事的商业价值的描述和故事卡片的拆分也进行了简单的分享。我同意每张故事卡都应该产生商业价值,我们应该明确地表达这个价值。在实践中,我发现“自由式”描述往往比“作为一个<角色>,我希望<功能>促进<商业价值>”更容易使用。比如某个需求是定期从主数据系统中获取最新的产品主数据,那么我就用这段文字来描述:总结:在目前的情况下,系统中的产品数据来自于客户——每个月副产品经理。Excel文件更新。客户自主研发的主数据平台已于上月正式上线,对外提供数据分发接口。我们可以通过它提供的产品主数据接口获取每天的产品主数据更新,解决手动更新的问题。及时、人工处理错误和其他问题。基于这种更自然的表达方式,我可以很容易地描述出更有价值的信息。最后对INVEST原则(写好用户故事应该满足的几个原则)有了一些理解:独立性(Independent):故事之间的强依赖关系应该尽量避免,但是如果一定要有强依赖关系,那么这些卡片应该可以在同一次迭代中完成。相关故事在估计、优先排序和开发技术解决方案时造成困难。避免强依赖的方法包括合并故事卡片、在另一个维度拆分故事等。可协商:实施方案可协商,但业务目标要明确;讨论是必要的,更不能就方案达成一致;讨论不是BA不提前想好具体方案的借口,更不是卡里的验收标准不明确。有价值:我想不出有什么理由让我们去做一个没有价值的需求。。。让我们把这篇文章理解为写这张卡片的时候,我们应该已经充分理解了它能解决的问题或者它能带来的好处,并且所有角色都同意这一点。可估计(Estimable):估计通常用于调度目的。为了能够估计故事的规模,故事应该足够小。团队应该对故事有充分的了解,能够对故事的内容和技术实现方案基本达成一致。足够小(Small):较小的故事有助于更准确的工作量评估或多人并行工作,可以让卡在卡片墙上的故事流动得更快,但没必要过分追求小故事,在很多情况下Dev在一次代码提交中同时处理两个相关的需求比一个接一个地处理这两个需求更简单高效。如果Dev经常说“让我一起打开这些卡片”或者“让我们关闭它们”,BA可以请教一下他的想法,也许你可以找到值得改进的地方。可测试:故事卡中描述的输入和输出清晰且可衡量。在文章的最后,我将总结一下我的观点。我同意故事卡中非常详细的描述可以带来价值,但我也相信“简洁的表达+充分的沟通”可以更高效、更灵活。我同意故事卡不是合同或合同,但我也相信完整准确的呈现可以显着降低角色之间的沟通成本。我同意工作软件优于详细的需求文档,但我也相信高质量的需求文档可以带来很多好处。我认同最佳实践和个人经验的参考价值(包括本文以上所有内容),但我认为因地制宜和团队建设的实践才是最好的选择。
