04 接到需求任务,你要先做哪件事?

我们书接上文,继续讲程序员小李的故事。

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

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

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

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

我想你已经嗅到了双方谈话的火药味,这个时候如果双方都不能很好地控制自己的情绪,那接下来一场体力的较量可能就一触即发了。

为什么双方会有这么大的分歧呢?

其中一个重要的原因是,开始实现这个需求之前,任务双方都没有清晰地定义好边界,没能把需求描述清楚

需求描述的问题

在软件开发中,程序员做什么一般都由需求来定义。

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

因为信息的传递是会衰减的,你不可能把你理解的信息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,也就是“行为驱动开发”),就可以按照验收标准中给出的内容编写验收测试用例了。

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

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

你的角色

或许你会有这样的疑问,如果产品经理通过用户故事的方式,将需求实现细节都描绘得清清楚楚,那我们程序员的发挥空间在哪里?

请注意,验收标准所给出实现细节应该是业务上的,程序员在这种问题上思考才是真正意义上的浪费时间,我们的发挥空间应该是在技术实现上。

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

你会发现,我们在开发中之所以会“丢三落四”,很重要的一个原因是,在开发一个功能特性的时候,因为一些环节的缺失,我们不得已扮演了很多的角色,其中之一就是产品经理。

你是一个专业的程序员,但大多数情况下,你却只是一个业余的产品经理,“丢三落四”就在所难免了。

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

没办法,答案只能是你自己。

虽然你名义上是程序员,但当拿到一个需求的时候,你要做的事不是立即动手写代码,而是扮演产品经理的角色,分析需求,圈定任务范围

相信我,事前分析绝对比你拿一个写好的系统给老板,而他却告诉你这不是他想要的,好太多了。

另外我想提醒你注意的是,扮演不同角色的时候,我们的思考模式是不同的。

还是以开发用户名密码登录为例,你想到的可能是:输入正确的用户名和密码可以正常登录,输入错误的用户名和密码不能登录,并且给出提示。

如果你只扮演开发人员的角色,想到这些就算不错了。

但如果你扮演的是产品经理的角色,会从产品的角度进行思考,也就会看到不同的内容,比如:

  • 登录是否需要验证码

  • 是否需要第三方登录

  • 用户名和密码的长度在系统内是否有限制

  • 密码是否需要满足一定的规则

……

我知道,如果让你来填写,这个列表会更长。

可能这并不是我们都需要完成的功能,但站在分析的角度,这都是我们要考虑的问题,一个登录功能,绝不仅仅是用户名和密码校验那么简单的。

我们能想到这些,仅仅是因为我们正在扮演一个不同的角色。

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

毕竟,最好维护的代码是没有写出来的代码。

总结时刻

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

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

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

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

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

如果今天的内容你只能记住一件事,那请记住:在做任何需求或任务之前,先定好验收标准

最后,我想请你回想一下,在实际工作中,你是如何澄清你的需求,或者因为需求不清晰给你造成了哪些困扰?欢迎在留言区写下你的想法。

05 持续集成:集成本身就是写代码的一个环节

上一讲我们探讨了需求的“完成”,你现在知道如何去界定一个需求是否算做完了,这要看它是不是能够满足验收标准,如果没有验收标准,就要先制定验收标准。

这一点,对于每一个程序员来说都至关重要。

在今天这一讲中,我们假设需求的验收标准已经制定清楚,接下来作为一个优秀的程序员,你就要撸起袖子准备开始写代码了。

不过在这里,我要问你一个问题:“是不是写完代码,工作就算完成了呢?”你或许会疑惑,难道不是这样吗?那我再问你:“代码是技术团队的交付物吗?”

你是不是发现什么不对劲了。

没有人需要这堆文本,人们真正需要的是一个可运行的软件

写代码是程序员的职责,但我们更有义务交付一个可运行的软件。

交付一个可运行的软件,通常不是靠程序员个体奋战就能完成的,它是开发团队协作的结果。

我们大多数人都工作在一个团队中,那我们写的代码是不是能够自然而然地就和其他人的代码配合到一起呢?显然没那么简单。

如果想将每个程序员编写的代码很好地组合在一起,我们就必须做一件事:集成。

但是集成这件事情,该谁做,该怎么做呢?我不知道你有没有思考过这个问题。在开始这个话题之前,我先给你讲个故事。

集成之“灾”

2009年,我在一个大公司做咨询。对接合作的部门里有很多个小组,正在共同研发一个项目。

他们工作流程是,先开发一个月,等到开发阶段告一段落,大项目经理再把各个小组最精锐成员调到一起开始集成。

对他们来说,集成是一件大事,难度很大,所以要聚集精英来做。

这个项目是用 C 语言编写的,所以,集成的第一步就是编译链接。大家把各个小组写好的程序模块编译到一起,哪个模块有问题,哪个小组的精英就出手解决它。

如果第一天,所有模块能够编译链接到一起,大家就要谢天谢地了。之后才进入到一个正式“联调”的过程。

“联调”的目标,是把一个最基本的流程跑通,这样,集成才算完成。而对他们这个项目来说,“联调”阶段更像是场“灾难”。

为什么?你想想,一个大部门有若干个团队,每个团队都在为同一个项目进行代码开发,周期为一个月。这一个月期间,所有团队的程序模块汇总在一起,体量会非常庞大。那么这些内容中,出现错误需要改动的可能性也就非常大,需要改动的量也就非常大。因此他们集成“联调”所需要的时间也会非常长。

即便他们调动各组精英,完成一次项目集成的时间至少也需要2~3天,改动量稍大,可能就要一周了。

虽然我不知道你所处公司的现状是什么样的,但大概率地说,你在职业生涯中,会遇到过类似的场景。那怎么去解决这个问题呢?

迈向持续集成

聪明的你作为旁观者一定会想,在这个故事里,为什么他们要在开发一个月后才做集成呢?

为什么不能在开发一周后,甚至是更短的时间内就集成一次?

这是一个行业中常见的痛点,所以,就会有人不断地尝试改进,最先取得的突破是“每日构建”。

1996年,Steve McConnel出版了一本著作《Rapid Development》,国内译作《快速软件开发》。

在这本书中,作者首次提出了解决集成问题的优秀实践:Daily Build,每日构建。通过这个名字,我们便不难看出它的集成策略,即每天集成一次。

这在当时的人看来,已经是“惊为天人”了。就像上面提到的例子一样,当时的人普遍存在一种错误认知:集成不是一件容易的事,需要精英参与,需要很长时间,如果每天都进行集成,这是想都不敢想的事情。

实际上,每日构建背后的逻辑很简单:

既然一段时间累积下来的改动量太过巨大,那一天的时间,累积的改动量就小多了,集成的难度也会随之降低

你会看到,对比最后做集成和每日构建,这两种不同的做法都是在处理改动量和集成时间的关系。

只不过,一个是朝着“长”的方向在努力,一个则瞄准“短”的方向。最后的事实证明,“长”的成了恶性循环,“短”的成了最佳实践。

既然,我们认同了只要增加集成的频率,就可以保证在每次集成时有较少的改动量,从而降低集成难度。

那问题来了?究竟要在开发后多久才进行一次集成呢?是半天、两个小时、还是一个小时呢?倘若这个想法推演到极致,是否就变成了只要有代码提交,就去做集成?

没错,正是基于这样的想法,有人尝试着让开发和集成同时进行,诞生了一个关于集成的全新实践:持续集成

持续集成一个关键的思维破局是,将原来分成两个阶段的开发与集成合二为一了,也就是一边开发一边集成。

持续集成这个想法固然好,但是不是需要有专人负责盯着大家的工作,只要有人提交了代码,这个负责人就要去集成呢?显然,这在真实工作中是行不通的。

既然是程序员的想法,程序员解决问题的方案自然就是自动化这个过程。

于是,有人编写了一个脚本,定期去源码服务器上拉代码,出现程序更新时,就自动完成构建。

后来,人们发现这段脚本与任何具体项目都是无关的。

于是,把它进一步整理并发布出来,逐步迭代发展成为今天广为人知的持续集成服务器。

在2000年时,“软件行业最会总结的人” Martin Fowler 发布了一篇重量级文章“Continuous Integration”。

之后一年,由 Martin Fowler 所在的 ThoughtWorks 公司发布了市面上第一款持续集成服务器 CruiseControl。

CruiseControl 可谓是持续集成服务器的鼻祖,后来市面上的服务器基本都是在它的基础上改良而来的。

Martin Fowler 的重磅文章和首款持续集成服务器的问世,让软件行业对持续集成进行了更为深入的探讨,人们对于持续集成的认知程度一路走高,持续集成服务器成为了开发团队在集成阶段最得心应手的工具。围绕着持续集成的一系列行为准则逐渐成型。

以至于发展到2006年,Martin Fowler 不得不重写了“Continuous Integration”这篇文章。之后人们更是以持续集成为基础,进一步拓展出持续交付的概念。

人类对工具是有偏爱的,持续集成服务器的发布,将持续集成从一项小众实践逐步发展成为今天行业的“事实”标准。

地面上”的持续集成

然而,即便持续集成已经发展多年,至今整个行业在对它的应用上,却并未达到同步的状态。

有趣的是,有一部分公司虽然还无法实现持续集成,但是因为持续集成服务器的出现,反而可以做到每日构建。

这不难理解,每日构建的概念虽然早早就提出来了,但在那个时期,行业里真正践行每日构建的公司并不多,其根本原因就在于,每日构建最初都是一些指导原则,缺乏工具的支持。

而每日构建和持续集成最根本的区别在于构建时机,而这只是持续集成服务器的一个配置选项而已。

当然,行业内有一部分公司已经可以将持续集成运用得得心应手,而也有相当大的一部分人还在为集成而痛苦不堪,比如我前面提到的咨询项目。

这个项目是我在2009年时参与的。

也就是说,此时距离 Martin Fowler 最初写下“Continuous Integration”已经过去了9年,甚至距离这篇文章的更新版发布也已经过去了3年,更不要说距离 McConnell 提出“每日构建”已经13年。

即便以当时的时间坐标系来看,这个项目的集成实践水平至少落后行业10年以上。

没错,他们甚至连每日构建都还差很远。

时至今日,持续集成早就是成熟得不能再成熟的实践了。然而,据我所知,许多公司依然处于集成要依赖于“英雄”的蛮荒阶段。

虽然我们在同一个时代写代码做开发,但在技术实践层面,不同的团队却仿佛生活在不同的年代。这也是我们要学习的原因。

也许,目前国内对于持续集成的实践水平还处于较为原始的状态,这是个坏消息。但好消息是,我们可以通过更多的学习,对集成有足够的了解,从而一步到位地进入到最先进的状态中。

无需停留在以精英为核心的集成时代,也可以完全不理会每日构建,我希望你拥有这个时代的集成观,直接开始持续集成。

如果有了持续集成的集成观,我们该怎么看待开发这件事呢?

开发和集成就不再是两个独立的过程,而是合二为一成为一体。

基于这样的理解,我们就不能再说代码写完了,就差集成了,因为这不叫开发的完成。一个好的做法是尽早把代码和已有代码集成到一起,而不应该等着所有代码都开发完了,再去做提交。

怎样尽早呢?你需要懂得任务分解,这是我们在之后的“任务分解”主题下会讲到的内容。

总结时刻

在软件开发中,编写代码是很重要的一环,但程序员的交付物并不应该是代码,而是一个可工作的软件。

当我们在一个团队中工作的时候,把不同人的代码放在一起,使之成为一个可工作软件的过程就是集成。

在很长一段时间内,集成都是软件行业的难题,改动量和集成时间互相影响。

幸运的是,不同的人在不同的方向尝试着改变,结果,同时加大改动量和集成时间的人陷入了泥潭,而调小这两个参数的人看到了曙光。

每日构建作为早期的一种“最佳实践”被提了出来,但因为它基本上都是原则,没有得到广泛的应用。当人们进一步“调小”参数后,诞生了一个更极致的实践:持续集成,也就是每次提交代码都进行集成。

真正让持续集成成为行业最佳实践的是,Martin Fowler 的文章以及持续集成服务器。持续集成的思维让我们认识到,开发和集成可以合二为一。我们应该把开发的完成定义为代码已经集成起来,而站在个体的角度,我们应该尽早提交自己的代码,早点开始集成。

如果今天的内容你只能记住一件事,那请记住:尽早提交代码去集成。

最后,我想请你分享一下,在实际工作中,你遇到过哪些由集成带来的困扰?欢迎在留言区写下你的想法。

06 精益创业:产品经理不靠谱,你该怎么办?

前面谈到验收标准时,我们说的实际上是确定性需求,也就是说,我们已经知道了这个需求要怎么做,就差把它做出来了。

而有时候,我们面对的需求却是不确定的,比如,产品经理有了一个新想法,那我们该如何应对呢?

今天,我们从 IT 行业一个极为经典的话题开始:程序员如何面对产品经理。我先给你讲一件发生在我身边的事。

有一次,我们一大群人在一个大会议室里做一个产品设计评审,来自产品团队和技术团队的很多人都参与到这个评审中。

一个产品经理正对着自己的设计稿,给大家讲解一个新的产品特性。

这个公司准备将自己的服务变成了一个云服务,允许第三方厂商申请,这个产品经理给大家讲解的就是第三方厂商自行申报开通服务的流程。

听完前面基本情况的介绍,我举手问了几个问题。

我:这个服务会有多少人用?
- 产品经理:这是给第三方厂商的人用的。
- 我:我问的是,这个服务会有多少人用。
- 产品经理:每个第三方厂商的申请人都会用。
- 我:好,那你有预期会有多少第三方厂商申请呢?
- 产品经理:呃,这个……我们没仔细想过。

- 我:那现在给第三方厂商开通服务的具体流程是什么。
- 产品经理:第三方厂商申请,然后,我们这边开通。
- 我:好,这个过程中,现在的难点在哪里?这个审批过程能让我们的工作简化下来吗?
- 产品经理:……- 

我:那我来告诉你,现在开通第三方厂商服务,最困难的部分是后续开通的部分,有需要配置服务信息的,有需要配置网络信息的。
目前,这个部分还没有很好的自动化,前面审批的部分能够自动化,对整个环节优化的影响微乎其微。

我的问题问完了,开发团队的人似乎明白了什么,纷纷表示赞同我的观点。

这个审批流程本身的产品设计并不是问题,但我们的时间和资源是有限的,关键在于,要不要在这个时间节点做这个事。准确地说,这是优先级的问题。

此刻,作为开发团队一员的你,或许会有种快感,把产品经理怼回去,简直大快人心。

好吧,作为一个正经的专栏,我们并不打算激化产品经理和开发团队的矛盾,而是要探讨如何做事情才是合理的。

之所以我们能很好地回绝了产品经理不恰当的需求,是因为我们问了一些好问题,但更重要的是,我们为什么能问出这些问题。

产品经理是个新职业

在做进一步讨论之前,我们必须认清一个可悲的现状,IT 行业中大多数人的专业程度是不够的。

IT 行业是一个快速发展的行业,这个行业里有无数的机会,相对于其它行业来说,薪资水平也要高一些,这就驱使大量的人涌入到这个行业。

也因为这是一个快速发展的行业,很多职位都是新近才涌现出来的,比如,在2010年之前很少有专职的前端工程师,之前的工程师往往要前后端通吃。

产品经理便是随着创业浪潮才风起云涌的职位。既然这是个“新”职位,往往是没有什么行业标准可言的。

所以,你会看到很多行业乱象:很多人想进入IT行业,一看程序员需要会写代码,觉得门槛高,那就从产品经理开始吧!这些人对产品经理岗位职责的理解是,告诉程序员做什么。

这和郭德纲口中外行人“如何认识相声”是一个道理,以为会说话就能说相声,殊不知,这是个门槛极高的行业。

产品经理也一样,没有良好的逻辑性,怎么可能在这个行业中有好的发展。

如果你遇到的产品经理能给出一个自洽的逻辑,那么恭喜你,你遇到了还算不错的产品经理。

多说一句,这个行业中专业度不够的程序员也有很多,人数比产品经理还多,道理很简单,因为程序员的数量比产品经理的数量多。

这么说并不是为了黑哪个职位,而是要告诉大家,我们必须要有自己的独立思考,多问几个为什么,尽可能减少掉到“坑”里之后再求救的次数

回到前面的主题,我们该怎么与产品经理交流呢?

答案还在这个部分的主题上,以终为始。我们是要做产品,那就需要倒着思考,这个产品会给谁用,在什么场景下怎么用呢?

这个问题在 IT 行业诞生之初并不是一个显学,因为最初的 IT 行业多是为企业服务的。企业开发的一个特点是,有人有特定的需求。

在这种情况下,开发团队只要把需求分析清楚就可以动手做了,在这个阶段,团队中的一个关键角色是业务分析师。即便开发出来的软件并不那么好用,企业中强行推动,最终用户也就用了。

后来,面向个人的应用开始出现。

在 PC 时代和早期的互联网时代,软件开发还基本围绕着专业用户的需求,大部分软件只要能解决问题,大家还是会想办法用起来的。

但是随着互联网深入人心,软件开始向各个领域蔓延。越来越多的人进入到 IT 行业,不同的人开始在各个方向上进行尝试。

这时候,软件开发的主流由面向确定性问题,逐渐变成了面向不确定性问题。

IT 行业是这样一个有趣的行业,一旦一个问题变成通用问题,就有人尝试总结各种最佳实践,一旦最佳实践积累多了,就会形成一套新的方法论。

敏捷开发的方法论就是如此诞生的,这次也不例外。

精益创业

最早成型的面向不确定性创造新事物的方法论是精益创业(Lean Startup),它是 Eric Ries 最早总结出来的。

他在很多地方分享他的理念,不断提炼,最终在2011年写成一本同名的书:《精益创业》。

看到精益创业这个名字,大多数人会优先注意到“创业(Startup)”这个词。

虽然这个名字里有“创业”二字,但它并不是指导人们创业挣大钱的方法论。正如前面所说,它要解决的是面向不确定性创造新事物。

只不过,创业领域是不确定性最强而且又需要创造新事物的一个领域,而只要是面向不确定性在解决问题,精益创业都是一个值得借鉴的方法论。

比如,打造一个新的产品。

精益创业里的“精益”(Lean)是另外一个有趣的词。

精益这个词来自精益生产,这是由丰田公司的大野耐一和新乡重夫发展出来的一套理论。

这个理论让人们开始理解价值创造与浪费之间的关系。

创造价值是每个人都能理解的,但减少浪费却是很多人忽略的。所以,把这几个理念结合起来,精益创业就是在尽可能少浪费的前提下,面向不确定性创造新事物。

那精益创业到底说的是什么呢?其实很简单。

我们不是要面向不确定性创造新事物吗?既然是不确定的,那你唯一能做的事情就是“试”。

怎么试呢?试就要有试的方法。

精益创业的方法论里,提出“开发(build)-测量(measure)-认知(learn)”这样一个反馈循环。

就是说,当你有了一个新的想法(idea)时,就把想法开发成产品(code)投入市场,然后,收集数据(data)获取反馈,看看前面的想法是不是靠谱

得到的结果无非是两种:好想法继续加强,不靠谱的想法丢掉算了。

不管是哪种结果,你都会产生新的想法,再进入到下一个循环里。在这个反馈循环中,你所获得的认知是最重要的,因为它是经过验证的。

在精益创业中,这也是一个很重要的概念:经过验证的认知(Validated Learning)。

既然是试,既然是不确定这个想法的有效性,最好的办法就是以最低的成本试,达成同样一个目标,尽可能少做事。

精益创业提出一个非常重要的概念,最小可行产品,也就是许多人口中的 MVP(Minimum Viable Product)

简言之,少花钱,多办事。

许多软件团队都会陷入一个非常典型的误区,不管什么需求都想做出来看看,殊不知,把软件完整地做出来是最大的浪费。

你为什么要学习精益创业?

或许你会问,我就是一个程序员,也不打算创业,学习精益创业对我来说有什么用呢?

答案在于,精益创业提供给我们的是一个做产品的思考框架,我们能够接触到的大多数产品都可以放在这个框架内思考。

有了框架结构,我们的生活就简单了,当产品经理要做一个新产品或是产品的一个新特性,我们就可以用精益创业的这几个概念来检验一下产品经理是否想清楚了。

比如,你要做这个产品特性,你要验证的东西是什么呢?

他要验证的目标是否有数据可以度量呢?

要解决的这个问题是不是当前最重要的事情,是否还有其他更重要的问题呢?

如果上面的问题都得到肯定的答复,那么验证这个目标是否有更简单的解决方案,是不是一定要通过开发一个产品特性来实现呢?

有了这个基础,回到前面的案例中,我对产品经理提的问题,其实就是在确定这件事要不要做。

事实上,他们当时是用一个表单工具在收集用户信息,也就是说,这件事有一个可用的替代方案。

鉴于当时还有很多其它需求要完成。我建议把这个需求延后考虑。

总结时刻

程序员与产品经理的关系是 IT 行业一个经典的话题。许多程序员都会倾向于不问为什么就接受来自产品经理的需求,然后暗自憋气。

实际上,产品经理是一个新兴职业,即便在 IT 这个新兴行业来看,也算是新兴的。

因为从前的 IT 行业更多的是面向确定性的问题,所以,需要更多的是分析。

只有当面向不确定性工作时,产品经理才成为一个行业普遍存在的职业。所以,在当下,产品经理并不是一个有很好行业标准的职位。

比较早成型的面向不确定创造新事物的方法论是精益创业,它提出了“开发(build)-测量(measure)-认知(learn)”这样一个反馈循环和最小可行产品的概念。

当产品经理让我们做一个新的产品特性时,我们可以从精益创业这个实践上得到启发,向产品经理们问一些问题,帮助我们确定产品经理提出的需求确实是经过严格思考的。

如果今天的内容你只记住一件事,那请记住:默认所有需求都不做,直到弄清楚为什么要做这件事

最后,我想请你回想一下,你和产品经理日常是怎样做交流的呢?欢迎在留言区写下你的想法。

参考资料

http://learn.lianglianglee.com/%e4%b8%93%e6%a0%8f/10x%e7%a8%8b%e5%ba%8f%e5%91%98%e5%b7%a5%e4%bd%9c%e6%b3%95/04%20%e6%8e%a5%e5%88%b0%e9%9c%80%e6%b1%82%e4%bb%bb%e5%8a%a1%ef%bc%8c%e4%bd%a0%e8%a6%81%e5%85%88%e5%81%9a%e5%93%aa%e4%bb%b6%e4%ba%8b%ef%bc%9f.md