更新时间:2024-11-08 GMT+08:00
分享

我在CodeArts做需求

秉承吃狗粮的文化,CodeArts团队在践行精益敏捷DevOps的同时,也在使用CodeArts工具进行实践落地。

需要说明的是:

  • 本文中提到的实践方式,CodeArts团队在践行,所以具有一定的示范性。
  • 不具备普适性,每个团队都应该根据自己团队的业务特性、团队成熟度、流程以及对方法论的解读,来进行落地实现。
  • 里面有很多优化的空间,并没有最好的实践,只有适合的实践。

通常而言,软件开发起始于需求收集与分析,所以本文从需求谈起。

传统的瀑布研发模式基于三个假设:

  • 用户准确的知道自己想要什么。
  • 开发人员能够完全理解用户在说什么。
  • 需求在研发过程中不会发生变化。

但事实上这三个前提假设都不存在,需求沟通之后做出来的产品,往往与需求大相径庭。

我们以用户故事来描述需求

维基百科上说,用户故事的目的在于以更快的速度、更少的消耗来应对现实世界需求的快速变化。在CodeArts中,我们以用户故事的形式来记录需求。

华为以往也用需求规格说明书以及用例的形式,但这样的方式非常乏味、容易出错、编写耗时,而且说真心话没人愿意去读。

采用用户故事的好处在于:

  • 用户故事强调对话而不是书面沟通。
  • 故事更容易被客户和开发人员理解。
  • 用户故事大小适中,适合做迭代计划。
  • 用户故事鼓励重要的事情先做。
  • 鼓励推迟决策,延迟考虑细节。
  • 支持随需求而变的开发。

用户故事将重点从以往的文档转换到了更实用的对话。面面俱到的文档看上去固然很美,但费时费力而且还没人去看。取而代之以通过与客户沟通来获取需求,通过与用户协作来澄清需求,通过频繁的发布来确认需求。

用户故事通常按照如下的格式来表达:

  • As a <Role>, I want to <Activity>, so that <Business Value>.

    作为一个<角色>,我想要<活动>,以便于<商业价值>

三段式的用户故事,核心是从用户角度出发描述问题,站在用户的立场思考问题。

好的用户故事讨论的是为谁做和为什么做,而不仅仅是做什么。作为Who,我想要What,以便于Why。有了Who、Why、What的信息,How就变得呼之欲出了。以往我们上来就写需求的,往往注意到的是What(干什么),却忽略了Who(为谁做)以及Why(为什么做)。而Who>Why>How>What的逻辑模式,恰好也是影响地图的结构。

CodeArts支持工作项模板,在设置 > 项目设置中,可以看到如何将用户故事的三段式,预置在Story的工作项模板中,也可以根据需要自行定义描述信息。

我们遵循Ron Jeffries提出的原则

关于用户故事,Ron Jeffries用3个C来描述它:

  • Card(卡片):我们在用户故事编写工作坊中使用贴纸或卡片编写,随后录入到CodeArts成为工作项,展现方式可以是卡片、列表或树状结构。卡片代表需求而不是记录需求,详尽的需求内容可以用其他文档表述。
  • Conversation(讨论):讨论的过程建议是面对面的,如果与CodeArts的成员一样,分布在不同地域,可以通过电话或IM工具(华为内部用eSpace,可以聊天,也可以语音、视频)进行,将重要的结论写在工作项提供的讨论功能中。简单的讨论可以直接通过工作项的讨论进行,但需要牢记的是,文字的讨论永远无法取代面对面或是电话的沟通。
  • Confirmation(确认):用户故事并不具备契约性质,达成协议的验证要点是测试的依据,用来验证用户故事是否符合用户的期望。在用户故事编写工作坊中,验证信息可以写在故事卡片的背面,随后录入工作项。针对每一个测试要点都应该变成完整的测试用例,测试用例会与需求进行关联,由此完美的将3C结合在一起。

在CodeArts中的用户故事:

  • 卡片是用户故事的展现形式,我们会切换到迭代视图的卡片模式,通过拖动卡片完成状态更新。
  • 讨论是沟通的方式,不要让讨论的内容蒸发掉,讨论过程中最大的浪费就是大量的信息随后被遗失掉了。我们通常在Story工作项的评论中记录讨论结果,或是直接在评论中进行讨论,并用@通知他人。
  • 确认是验收方式,验收信息可以填写在描述信息中,也可以在项目设置中在Story工作项的模板中添加一个属性字段完成,具体实现方式不一,并且实现起来非常灵活,所以并未做进预置的项目模板中。

一个用户故事工作项,事实上是一个需求的入口,以条目化或是卡片的形式展现,同时可以进行多方位的关联。

  • 由验收信息生成的测试用例,会关联到工作项的“关联用例”中。
  • 在对话和沟通的过程中会产生的有用信息,可以通过Wiki(知识共享)、Docman(文档协同)来保存,并且可以关联到Story工作项。
  • 可以将现有的文件添加为工作项的附件。

如何创建和收集故事?

通常有几种方式进行用户故事的创建和收集,其中前两种是最经常采纳的:

  • 用户访谈
  • 故事编写工作坊
  • 问卷调查
  • 观察

用户访谈的关键是找到真正的用户,所以用户访谈之前是用户画像,也就是找到Who的过程。

“你们的确开发了我所说的功能,但它并不是我真正想要的”,用户往往不知道或很难准确表达自己想要的,所以沟通需要频繁,需要拿着不同阶段的产物进行确认。说者无心,听者有意,会不会是自己主观臆断?说者有心,听者无意,会不会遗漏关键字?同理心说起来容易,做起来很难。

用户故事编写工作坊是捕获需求最有效的方式,原则是:数量优先而不是质量优先,鼓励大家输出,而不要去评判某个故事的好坏;深度优先而不是广度优先,先把一条路走通,而不要中途跳到岔路上。用户最可能做什么?可能会犯什么错误?会有什么困惑?会需要什么信息?在工作坊里最好用贴纸,便于交互,随后再整理到工具平台上。

观察用户真实使用产品的机会是难能可贵的,你会发现用户永远不会按照你设计的方式使用产品。

如何拆分用户故事

需求通常以“Epic>Feature>Story”进行层级拆分:

  • Epic通常是公司重要战略举措或者巨大的需求,例如做一个电商网站就是一个Epic。
  • Feature通常是在Epic之下,对用户有价值的功能,用户可以通过使用特性满足他们的需求。比如“电商网站”的 “门店网络查询功能”,特性通常会通过多个迭代持续交付。
  • Story通常是对一个功能进行用户场景细分,并且能在一个迭代内完成,Story通常需要满足INVEST原则:Independent(独立的),Neogotiable(可讨论的),Valuable(对客户/用户有价值的),Estimable(可估计的),Small(小的),Testable(可测试的)。
  • Story又可以继续拆成Task,Task是实现层面的,无需遵循INVEST原则。

战略、功能、需求、任务等的在具体项目中很难进行归类,也可以简单的按月、周、日、小时为单位进行判断,通常一个Epic可能会跨多个Release交付,Feature跨多个Sprint,Story需要在一个Sprint中完成,而Task通常是更短小以小时至多以天计。

  • 在CodeArts中,从Epic>Feature>Story的拆分,可以在“项目规划”里以脑图的形式进行,一目了然。也可以在工作项页面中,以树状关系来展现和拆分。

非功能性需求以及技术类需求

非功能性需求(Non Functional Requirement)往往是决定产品或项目成败的关键,却往往容易被忽视。当非功能性需求欠缺太多,就背负了技术债务,需要通过定期的技术类活动进行清理。

  • 典型的非功能性需求包括:性能、可移植性、可扩展性、可用性、易用性、可维护性、可重用性、可操作性、安全性、容量等。
  • 技术类需求的例子包括:重构、搭建持续交付流水线、测试自动化活动、环境的维护与搭建、架构改造等。

目前CodeArts没有预置非功能性需求和技术类需求作为单独的工作项类型,不希望工作项类型过于膨胀而增加了使用的复杂性。

通过新增字段可以标识不同类型的需求,更好的方式则是采用Tag标签。善用标签和过滤器的结合,可以实现非常强大的功能,关于过滤器的使用技巧,我们可以单开一个主题来讨论。

如何识别用户故事的坏味道BadSmell

如同低质量的代码会有Bad Smell,用户故事也一样会有坏味道:

  • 几十页上百项需求堆在Product Backlog里。
  • 提交的需求,自始至终没人和你沟通,某一天突然发现需求被实现了。
  • 排在Product Backlog中段和后段的用户故事太过详尽。
  • 大家依赖Product Backlog电子系统,而不是面对面进行沟通。
  • 用户故事长得像需求规格说明书。
  • 说不出故事的目标用户以及带来的价值。
  • 很难为众多故事排优先级(不是高中低,而是唯一顺序)。
  • 故事之间牵一发而动全身。

如果你发现上面任意一条出现在你的项目中,那说明你的用户故事还需要改进。

有关用户故事的一些零散建议

  1. 需求要有时间点。多问一句“什么时候需要?”,你往往会发现对方其实心里没数,ASAP不是一个好答案,越快越好只能说明不信任。尽管会有顾虑,我依然会如实说“这个功能与一个月之后的某个活动相关,在此之前实现即可,但需要预留给我一周的时间进行验证和修复”。
  2. 进行故事优先级排序时,需要考虑成本,一个重要的需求,有可能因为成本过高而延后,另一种方法是对其进行拆分。
  3. 不要着急给用户故事添加细节,遵循Kent Beck提出的最后责任时刻原则(Last Responsible Moment),团队要等到开始实现软件特性前才写下特性的具体细节,优先级排序,近期、中期、长期需求的详略程度。
  4. 纸质卡片、贴纸,还是电子工具?
    • 在需求收集和引导的前期,例如需求编写工作坊,建议采用纸质卡片,便于交互,并且卡片的有限文字空间保证了我们不会过早进入细节。
    • 当需求收集告一段落,统一将需求录入到CodeArts平台,需求不只是Card一个维度,多方位的信息需要有工具平台来支撑和记录。同时平台也提供了团队成员之间的协同,CodeArts团队异地的协同场景就是基于CodeArts平台进行的。

小结

故事是讲出来的,不是写出来的。故事的目的是激发沟通中的火花,用户故事之所以叫故事,是因为他要讲而不是要写的,沟通、协作并最终交付好的需求。

CodeArts的需求实践并非最好的,只是适应我们自身团队以及产品/项目情况的折中之选。

本文参考资料

  • 《用户故事与敏捷方法》 Mike Cohn
  • 《敏捷革命》 Jeff Sutherland

相关文档