小李接到一个新的需求,让他开发一个单点登录的服务,经过几天的奋战,他顺利地写完了所有的代码。正好产品经理小王路过他身边,顺便问了他一下。

小王:单点登录做得咋样了?
小李:做完了,我给你演示一下。

小李演示了一遍自己做的功能,小王看上去很满意。

小王:不错。不过,怎么没有支持验证码?
小李:为什么要做这个?
小王:这不就是登录的一部分吗?
小李:哪里规定要做验证码了?
小王:现在做登录哪有不用验证码的?

我想你已经嗅到了双方谈话的火药味,这个时候如果双方都不能很好地控制自己的情绪,那接下来一场体力的较量可能就一触即发了。为什么双方会有这么大的分歧呢?其中一个重要的原因是,开始实现这个需求之前,任务双方都没有清晰地定义好边界,没能把需求描述清楚。

需求描述的问题

在软件开发中,程序员做什么一般都由需求来定义。我们都知道,需求是软件开发的一个重要组成部分,但你可能并没有仔细想过,不同的需求描述方式,可能会影响我们程序员对需求的理解。

因为信息的传递是会衰减的,你不可能把你理解的信息 100% 传递给另外一个人,而这中间,如何传递,也就是如何描述将直接决定衰减的比例。

很多公司的软件开发模式是基于功能列表的,这个列表“规定”了程序员要做的功能,各个组从产品经理那里领来开发列表,然后“照单抓药”开始写代码。但是,通常这种功能列表只是一些简单的描述,你并不能看到全局。

很多团队的一个状态就是,程序员们都知道要开发的功能是什么,但这个功能是谁在什么样的场景下使用的,很多人却回答不上来。如果你去问他为什么要开发这个功能,他通常会说:这是功能列表里规定的。

这种功能列表式的需求描述方式,将一个完整的需求敲成了碎片。 只有所有功能全部开发完成,对接在一起的时候,才是“破镜重圆”的时刻。

也就是说,不到最后一刻,大多数人并没有一个完整的图景,这就相当于看不到完整的“终”。顺着这个思路做下去,你会在最后关头遇到许多意料之外的问题,其结果必然是手忙脚乱。

根据这种基于功能列表的需求描述,每个组在安排工作的时候,都会按照自己的理解进行功能排列。

所以,当你的组完成了一个功能时,这个功能却可能上不了线,因为你还要依赖于其他组的工作,而这个组不巧,却刚好把相关的功能开发排在了后面。

这还只是两个组之间有依赖的情况,如果需要多个组协同,可以想象,状况会多么糟糕。

所以,当我们对产品经理说“时间不足,砍掉一些需求吧。”得到的答案肯定是,“对不起,做不到,因为需求已破碎,没办法调整。”

因此,一些新的需求描述方式也就应运而生,这其中,用户故事(User Story)是我最喜欢的一种方式。它是站在用户的角度来描述了一个用户希望得到的功能,关注用户在系统中完成一个动作需要经过怎样的路径。既然它是“故事”,它就需要是一个完整的场景,可以讲述出来。

“用户故事”有什么用?

我们先来以用户密码登录为例,看看用户故事长什么样?一个完整的用户故事大致包含以下几个部分:

  • 标题,简要地说明这个用户故事的主要内容,比如:注册用户使用用户名密码登录。
  • 概述,简要地介绍这个用户故事的主要内容,一般会用这样的格式:
    As a (Role), I want to (Activity), so that (Business Value).
    意思就是:作为一个什么角色,要做什么样的事,以便达成一种怎样的效果。其中最重要的是,告诉别人为什么要做这件事,虽然只有一句话,却往往是很多人欠缺的思考,只知做,不知为何做。
    举个概述的例子:作为一个注册用户,我想要通过用户密码登录,以便我可以使用注册用户才能够使用的服务。
  • 详述,详细地描述这个用户故事的完整流程,我们会把操作流程、用户界面等信息都放到这里。
    比如:用户使用正确用户名和密码登录,就可以登录成功;如果密码不正确,则登录页面提示用户“用户名密码不正确”。基本上,看到这个部分,程序员就可以在心中描绘出这个用户故事的样子了。
    超出范围的部分,比如:第三方登录不在范围内,这个部分主要是限定人们不要进一步发散。
  • 验收标准,这个部分会描述一个正常使用的流程是怎样的,以及各种异常流程系统是如何给出响应的,这是程序员常常会欠缺的思考。它会把详述中很多叙述的部分变成一个具体的测试用例。比如,下面我给出的两个验收用例:
    正常场景:给定一个注册用户张三,其用户名是 zhangsan,密码是 foobar,当张三使用 zhangsan 和 foobar 登录系统时,可以成功登录,登录成功后,跳转到用户中心。
    异常场景:给定一个注册用户张三,其用户名是 zhangsan,密码是 foobar,当张三使用 zhangsan 和 wrong 登录系统时,登录失败,在登录页面上提示“用户名密码不正确”。

在前面的例子中,小张和小王之所以会对需求是否完成产生分歧,是因为大家对于需求完成的定义不同。对于这种情况,我们能怎么办呢?

这个模块的主题是“以终为始”,现在你看到了用户故事是如何描述需求的,你或许已经知道我要说什么了,没错,这里非常关键的一点就是“验收标准”。很多人学习用户故事,认为最重要的是记住“As…, I want to …, so that …”这样的需求描述方式。

在我看来,无论采用哪种需求描述方式,这部分也都是能说清楚的。那我们要从用户故事中学到什么呢?我认为就是用户故事的关键点:验收标准,它可以清晰地定义出需求边界。

验收标准非常重要的一环是异常流程的描述。大部分程序员都擅长解决正常流程,而异常流程则是最容易忽略的,也是产生扯皮的关键环节。既然容易扯皮,我们就在一开始把它定义清楚。怎么才算做完需求呢?验收标准说了算。

采用用户故事之后,我经常在写完了主要流程之后,再去看一下验收标准,为自己的开发查缺补漏。因为我知道,那是标准,达不成就不算任务完成。

当我们说自己开发完成,可以交给测试人员测试时,我们需要照着验收标准给测试人员演示一遍,证明我们的系统确实能够跑通。这之后,测试人员才会把系统接手过去,做更系统的测试。

验收标准给出了这个需求最基本的测试用例,它保证了开发人员完成需求最基本的质量。如果你了解 BDD(Behavior-Driven Development,也就是“行为驱动开发”),就可以按照验收标准中给出的内容编写验收测试用例了。

在实际工作中,许多产品经理把需求交给开发人员之前,很多细节是没想清楚的,那种功能列表式的需求常常只包含了正常路径,那些缺失的细节就是在后续的过程中,由开发人员补全的。用户故事就是一种固定的格式,让他们把这些应该想清楚的问题想清楚。

如果你的团队采用用户故事的格式进行需求描述固然好,如果不能,在功能列表中,补充验收标准也会极大程度地改善双方协作的效率

你的角色

或许你会有这样的疑问,如果产品经理通过用户故事的方式,将需求实现细节都描绘得清清楚楚,那我们程序员的发挥空间在哪里?请注意,验收标准所给出实现细节应该是业务上的,程序员在这种问题上思考才是真正意义上的浪费时间,我们的发挥空间应该是在技术实现上。

然而,在现实情况中,很多团队做不到这种程度。

你会发现,我们在开发中之所以会“丢三落四”,很重要的一个原因是,在开发一个功能特性的时候,因为一些环节的缺失,我们不得已扮演了很多的角色,其中之一就是产品经理。你是一个专业的程序员,但大多数情况下,你却只是一个业余的产品经理,“丢三落四”就在所难免了。

或许你会说,我在一个小公司工作,公司没那么多人,没有专门的产品经理,只有我们几个“全世界都缺”的程序员,需求都是老板扔给我们的,谁来帮我们写验收标准呢?

没办法,答案只能是你自己。虽然你名义上是程序员,但当拿到一个需求的时候,你要做的事不是立即动手写代码,而是扮演产品经理的角色,分析需求,圈定任务范围。相信我,事前分析绝对比你拿一个写好的系统给老板,而他却告诉你这不是他想要的,好太多了。

另外我想提醒你注意的是,扮演不同角色的时候,我们的思考模式是不同的。还是以开发用户名密码登录为例,你想到的可能是:输入正确的用户名和密码可以正常登录,输入错误的用户名和密码不能登录,而且给出提示。

如果你只扮演开发人员的角色,想到这些就算不错了。但如果你扮演的是产品经理的角色,会从产品的角度进行思考,也就会看到不同的内容,比如:

  • 登录是否需要验证码
  • 是否需要第三方登录
  • 用户名和密码的长度在系统内是否有限制
  • 密码是否需要满足一定的规则
  • ……
    我知道,如果让你来填写,这个列表会更长。可能这并不是我们都需要完成的功能,但站在分析的角度,这都是我们要考虑的问题,一个登录功能,绝不仅仅是用户名和密码校验那么简单的。我们能想到这些,仅仅是因为我们正在扮演一个不同的角色。

所以,如果你要兼顾开发人员和产品经理两个角色,建议你先扮演好产品经理的角色,多花点时间把验收标准制定好,再回到开发人员的角色上去写代码。毕竟,最好维护的代码是没有写出来的代码

总结

需求,是软件开发中的一个关键环节,一旦需求理解出现问题,势必会造成大量的浪费。传统的功能列表只是简单罗列了要实现的功能,丢失了大量的上下文,会导致团队成员对于需求“只见树木不见森林”。

而在比较大的团队中,更是会将一个功能分拆到多个小团队中,每个人看到的只是功能碎片。于是,后来产生了其他的需求描述方式,比如用例和用户故事。

在实际的开发过程中,大量的分歧来自于对“需求完成”的定义。当我们把“以终为始”的原则应用在需求领域中,就会注意到,用户故事有一个非常重要的组成部分是验收标准。

验收标准不仅仅描述出了正常流程,也会关注到异常流程的处理,它也是我们验收测试用例的起点。一旦事先定义好验收标准,大量的扯皮工作就随之烟消云散了。

理解了验收标准的作用,即便我们不使用用户故事来定义需求,依然可以把用户故事中的关键点应用到自己的实践中,在功能列表的每个功能定义中,增加验收标准。

请记住:在做任何需求或任务之前,先定好验收标准

【以终为始】接到需求任务,你要先做哪件事?相关推荐

  1. 解读10x程序员工作法-以终为始

    以终为始 以终为始:如何让你的努力不白费? 网上流传着一个帖子,亚马逊 CTO 介绍亚马逊是如何开发一项产品的,简单来说,他们采用向后工作的方法,开发一项产品的顺序为: 写新闻稿: 写 FAQ(常见问 ...

  2. 【以终为始】为什么说做事之前要先进行推演?

    经过前面的学习,想必你已经对"以终为始"这个原则有了自己的理解.你知道接到一个任务后,要做的不是立即埋头苦干,而是要学会思考,找出真正的目标.那目标明确之后,我们是不是就可以马上开 ...

  3. 以终为始,向死而生——5月份英语总结

    解释两个词 文章开头先来解释一下"以终为始,向死而生"这两个词的意思. 以终为始:先把想达成的目标想好,然后以此为目标,通过分解成小目标等方式来努力实现它. 解释:个人感觉这句话挺 ...

  4. C++ 开篇 长路漫漫,以终为始!

    给初学C++的职场新人的一些建议 1.了解语言基础:首先要掌握C++的基本概念和语法, 包括数据类型.运算符重载.面向对象编程等. 2.练习: 练习编写 C++ 代码以及解决常见问题,例如经典的算法和 ...

  5. chronodex怎么用_以终为始的时间流管理

    创作大纲 01 对我很有启发的管理术 1-1 来源:@rika 「以终为始」的时间管理 (图片来源:微博博主@rika-丽卡) 从我近五年接触手帐以来,个人的管理方法与博主rika大体相近,于是从她的 ...

  6. 【万字总结】以终为始,详细分析高考志愿该怎么填

    [万字总结]以终为始,详细分析高考志愿该怎么填 为什么写这篇文章? 之所以写本文,是因为我自己有用处. 我简要介绍,长话短说.我从一个普通的211本科毕业,已经接受社会"毒打"多年 ...

  7. 接到需求之后,产品经理如何高效的从“想”到“做”?

    咖友提问:接到需求后,应该考虑哪些?思路是怎样? 接到需求后,如果直接画图,就成了画图的了,应该如何考虑才能全面呢?生怕有遗漏的地方. ▍jory 环岛 推车手 各人有各人的工作习惯,各个团队之间也有 ...

  8. 九峰影业创始人_以终为始 逐梦青春——九峰实验学校2020届高三毕业典礼

    2020年7月11日下午1点,我校举行"以终为始,逐梦青春"2020届高三毕业典礼.校行政人员.学生家长.2020届高三全体师生参加了典礼. 典礼在国歌声中拉开序幕.宣沫校长作&l ...

  9. 高效能人士的2个习惯:以终为始与要事第一

    (题图: Title | 摄影: Who) 全文接近 6000 字,按 300 字/分钟的速度算,读完要 20 分钟,建议收藏阅读. 本文的组织结构如下:第一部分明确了习惯和高效能两个关键字的含义:第 ...

最新文章

  1. zepto打造一款移动端划屏插件
  2. 使用python函数计算3.5四舍五入的结果_python 数字的四舍五入-Go语言中文社区
  3. Swift教程之类和结构体
  4. NET问答: 如何让 HttpClient 支持 Http 2.0 协议?
  5. 英特尔发布全新高性能显卡品牌Arc,首款显卡将于 2022 年上市
  6. 计算机世界:免费的代价
  7. 在dos下或web下Fatal Error: undefined function mysql_connect()
  8. Spring中使用@Async注解使Even监听事件之间的执行变为异步
  9. mac 电脑 打开隐藏文件
  10. vue项目设置footer始终处于页面底部
  11. 完结撒花!吴恩达DeepLearning.ai《深度学习》课程笔记目录总集
  12. redit mysql_从 Reddit 学到的经验,互联网营销
  13. 两个可能常用到的几何知识(圆与椭圆的方程、求垂直向量)
  14. python方差膨胀因子_讲讲共线性问题
  15. Chrome 浏览器 原生工具进行网页长截图
  16. HP4230s笔记本安装mac os总结(原创)
  17. 4K超高清电视全面支持HDMI技术
  18. 黑盒测试方法五(场景法)
  19. 算法分析—大O、大Ω、大θ
  20. ios调用第三方程序打开文件,以及第三方调用自己的APP打开文件

热门文章

  1. 对话图灵奖得主Jeffrey Ullman:数据库不会进入周期性的坏循环|《新程序员》
  2. Keil MDK5.37以上版本自行添加AC5(ARMCC)编译器的方法
  3. 误删path等环境变量(系统变量/用户变量)
  4. IPv6 三个访问本地地址的小Tips
  5. 我们只是虫子!我们真的是虫子吗?
  6. Centos7下安装部署Zabbix-server 3.4
  7. 安卓把word转为html,把Word转为简洁的html的若干种方法
  8. 搜索引擎关键字智能提示实践
  9. 架构就是bull shit
  10. jQuery基础学习【博学谷学习记录】超强总结,用心分享