V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
niuer
V2EX  ›  程序员

用户需求驱动式的开发方法

  •  
  •   niuer · 2014-11-04 15:20:01 +08:00 · 1863 次点击
    这是一个创建于 3659 天前的主题,其中的信息可能已经有所发展或是发生改变。
    引言:开发者应该如何处理研发中的需求?在快速迭代的开发过程应该分为哪几个阶段?在一个快节奏的开发过程中,如何建立一个质量保障体系?七牛CEO许式伟在MDCC上的讲座《用户需求驱动式的开发方法》分享了他在开发过程中的一些心得。

    许式伟:大家好,先自我介绍一下,我叫许式伟,刚才主持人大概也介绍了一下,最早在金山做WPS Office ,2007年在金山实验室主要做存储相关的技术研究,2008年底加入了百度做网页搜索,2009年、2011年在盛大做存储相关的,2011年到现在在七牛,这是整个的经历。
    今天想分享七牛的研发方式,我们总体的总结式需求驱动的研发历程。这种方式有一个原则,就是功能需要和需求,功能和需求是要有一个对应关系,也就是说,如果一个功能是没有用户场景的话,我们认为这个是非常不可思议的。所以我们有一个原则,没有用户反馈过的需求是不做的,这样的功能如果对应不到用户的应用场景是不做的,哪怕你觉得这个功能确实很酷,也可能很多人用,但是没有任何人提过,说明这个事情并不重要。这是功能和用户场景的一个对应关系,也是需求驱动研发的核心思想。
    第二个,是不是用户反馈过的所有需求都要做呢?这个我们认为并不是这样子,而是说产品应该有一个非常明确的边界,在这个边界之内,因为一个产品发布之后必然会吸引着非常非常多的人使用,在使用的过程中,会有一些伪用户出现,也就是说实际上并不是你想要打动的用户群体,但是它可能对你这个产品有误解,就订了。所以我们认为应该围绕着需求驱动的核心想法上,首先要有一个产品定向的用户产品来定义,在这个定义的框架下,我们再探讨是不是这个用户的需求是值得做的。所以我们会根据用户反馈的需求来结合产品的定位,要分出这是一个不错的功能还是说这是一个优先级的,还是这是非常高的优先级的。所以我们认为需求驱动研发很重要的思想是产品要有一个明确的边界,以这个边界来确定功能是否做以及做的优先级是什么。
    比如说,七牛做面向开发者的云存储,云存储这个词非常泛,很多人理解不一样,自然而然有非常多的网盘类的客户被七牛吸引。大家知道,网盘是非常便捷的,在七牛的客户里面往往会提一些相对比较复杂的内容,复杂的需求,七牛拒绝了非常多的管理需求,原因很简单,七牛是面向开发者的一个云存储。我们设想的不是大众,非技术人员面临的那种内容管理的难题,而是说在七牛上有一个企业帐号,可能有上千万或者说上亿的文件的时候,会怎么管这些文件,围绕着这样思维场景来去设计内容管理,这两者有很大的区别。
    为什么我们会围绕着需求驱动的研发方式的价值,我觉得是这样,首先整个研发需要有地方的,任何开发中或者你的产品必然需要面向一个群体,而这个群体它对你产品的理解以及对你产品的使用体验是什么样的,是满意还是不满意。所以在整个研发过程,我们希望用户有一种参与感,并且在用户的反馈中来迭代往前。需求驱动的研发方式最核心的是希望能够以用户在研发的整个体系里面以便形成一个研发的地方,因为只有获得了充足的用户反馈之后,我们才能够往前走,知道产品改进的方向。
    在七牛的产品研发过程中,我们实际上迭代其实都非常快的,我们基本上是一周会有一次发布,甚至在中间如果有一些小改动,如果我们认为需要做的时候,中途会插入一些非常快速的东西,上午研发完了以后,下午可能就发布了,在一天内就会出来。这些根据APP的特性,有的是客户端APP,迭代周期不适合等,因为大家都知道,移动端的APP它的发布,用户升级周期会相对长一点,所以这时候我们建议可能是一个月,但是我们认为和用户交互并且快速迭代的方式会非常的适合面向需求式的开发。每个迭代周期的过程都会确定本周期的研发目标是什么,这个确定的过程其实很简单,因为我们有一个需求值的概念,这个需求值就是刚才我讲的根据用户反馈的需求,我们确定它不做还是说做,做的话,是优先级还是高优先级,我们就是从这个需求词里面挑一些我们认为高优先级的需求把它加入到下一步,一旦确定加入到下一步,它自然就会排入到研发的计划里面。
    研发的需求里面,刚才提的是用户需求也包括一定比例的研发故事,比如说重构,某个模块大家觉得它发展到一定的阶段以后,对它很不爽,它可能会有点技术老化的感觉,这时候我们会一定程度上插入技术故事这样的研发内容。很多公司非常期待快速迭代的思想,但是在这个快速迭代的思想中,为什么在公司没办法推动,我认为最重要的是质量保障体系的不完善,实际上在我看来,质量保障体系是让一个公司能够快速做迭代的技术。今天很大程度,我们如何保证发布的研发质量。在整个研发过程中,我们大致的把开发过程分为两个阶段,一个是开发阶段,一个是发布阶段,在开发阶段我们主要使用的手段,第一个,在一个分支上开发的,不是在主干上,如果了解这个开发都比较习惯,用SBN可能习惯在主干开发,我们认为基于分支的开发方式在快节奏的开发模式里面是非常重要的一种做法。第二个是单一测试;第三个是代码审查,这是在开发阶段我们做的质量保证相关的事情。
    在发布阶段只要通过集成测试和灰度发布这两个来保证发布的质量。
    我们先提一下在分支上来开发,实际上这个方式我觉得比较容易理解的,而且也非常容易,我大概地说一下,实际上所有的功能在分支上开发的好处非常简单,因为如果你这个功能还没有开发完,大家认为还不存在,功能完不完成对其他人是没有任何影响的,这样的好处非常的清楚。代码什么时候能够合并呢?合并的前提就是我刚才讲的开发阶段,我们有的质量保障方式都必须做完,比如说要有充足的单一测试,单一测试必须保证足够的覆盖率,要有代码审查,很多公司如果不是基于分支开发,可能在代码被合并之后才能够检查,实际上对这个代码不满意,它已经进入主干了,这时候就会有问题。所以我们其实把开发阶段和代码被合并到主干就叫开发阶段完成,后面属于发布阶段。在发布阶段我们其实考虑的是,代码开发完成了以后,并且它已经被合并到主干,这时候必然进入到beta测试环境,进行集成测试,集成测试完成就会被灰度的发布,所谓灰度发布就是让少量的用户或者少量的地区先感受到这个功能,让这个功能在小范围内被体验,以此来确定这个是不是需要更多的人去驱动它,还是让它回本等等。
    这整个过程,我们认为测试的自动化是非常非常重要的,所以我们谈谈自动化测试,因为很多公司,我相信特别做APP的公司,会选择用常规的测试方式,通常基于手工的方式,但手工测试不具有合规性,测试的效率是不高的。正因为缺乏效率,所以说往往导致测试只针对非常典型的场景,测试的覆盖率也会非常低,这两者我认为是有相关性的,因为你测试的效率越高的话,它的覆盖率越容易保证。我认为其实哪怕做APP开发,我们倾向于尽可能多的模块纳入到自动化的测试系统里面,当然也确实会由于一些基于UI方面的考虑,有一些操作是不太方便去做自动化的,我自己本人做过office,也是属于桌面,我知道这界面相关的,不同意义来说,分层分好的,绝大多数代码可以被测试,如果做一定的分层,在适度的情况下也是可以被测试的。自动化测试最重要的特征是自动化可回归的,所以它的主要思想是如果没有出错,其实不用做任何的显示,只有在它出错的时候,会报出在哪一行了等等。
    自动化测试其实是分两层面,一种我们认为单一测试,还有一种是集成测试,先说说单一测试,单一测试实际上是成本最低的自动化测试,为什么,因为它是模块级的测试,模块级的测试环境是最简单的,因为这个模块本身它非常小,所以如果对它的边界进行测试的话,它是最容易构建测试的配置。而集成测试,虽然有自动化的方法和支持工具,但是通常会有更高的代价,而且单一测试它最最大的好处是减少了问题,发现了周期,因为问题发现了周期越短其实修复的时间就越快。如果问题发生在集成期甚至是这个问题在发布之后才被发现的话,它整个定位和bug跟踪的过程,实际上比我在研发阶段就发现这个问题成本要几倍或者说几十倍的增长。
    所以我们认为单一测试是最关键的一个环节,如果你觉得集成测试更高的话,可以不妨从单一测试阶段做起。我们比较一下单一测试和集成测试,单一测试比较偏白盒测试,以功能为主,只有非常少量的单一测试会涉及到性能测试,只有那些非常关键的环节,这个在任何一个公司里面,这个模块都非常的少,单一测试发生在开发阶段,也就是开发人员正应该去做的。集成测试,其实往往偏向于有一个专门的测试团队去做的,它会偏向黑盒测试,对产品整体做一个覆盖性的测试,它还会做压力测试,因为在一个Beta环境整个系统非常完整的情况下,我们可以对它做非常持续的一个压力测试。所以像七牛会有一个专门的机房是用来往上面打流量,压力自己去测,这个功能在进入了主干之后,我每天会定期的去测试。
    我顺便提一个可能比较小的细节,但是我觉得非常重要,我们Bug处理过程,如果发现一个Bug,它应该先固化测试案例,也就是先用测试案例把它跑出来,首先代码发现了这个确实是个Bug,因为我已经用别的方式修复了,使用这个方法以后这个Bug不会出现了,因为整个上线过程中必然会经过,把所有固化的单一测试和计算机测试都会跑一遍。所以这个Bug不会再出现。修复Bug的过程其实是跟功能开发是一致的,基本上要有完整的经历,刚才讲的开发阶段和发布阶段的两个所有的流程。
    下面是代码审查,我不知道有多少公司做代码审查,能举一下手吗?非常少,这个也在我的想象中,因为代码审查其实是非常有价值一个东西,所以在七牛的代码审查非常严格,我们通常建议代码至少要经过两个人的应用,我们把它叫做两个阶段都是有各自的名词,一个叫做同事互审,一个是正式审核,代码审核其实能够发现非常多的问题。所以我们认为代码审核是白盒的代码质量保障的一个重要手段,它能够发现架构不合理、接口不合理,或者这个代码不带单元测试的案例,比较容易出问题但是没有写分支的文件,或者发现潜在的Bug等等,这样一些问题。单一测试直接覆盖,让开发人员第一阶段的单一测试,毕竟是自己写的功能,自己测的话会有一点的盲点,我觉得代码互审能够覆盖掉这个盲点。
    总结来讲,我们需要有一个在快节奏的开发的前提下,我们需要有一个质量保障体系,质量保障体系的价值在于如果质量体系越完善研发节奏就越快,这两个有很强的关联性。
    这是我跟很多开发人员提的一个叫做代码生命周期的一个概念,这个图我非常非常的喜欢,而且我经常和开发人员去提这样一个图,你的代码也可以非常粗糙的分成两个阶段,一个是开发阶段,一个是维护阶段,开发阶段是指代码或者这个模块是否提交了,比如说七牛刚才提的那个案子,我们把代码合并到了主干,就是代码的开发阶段完成了,此后这个代码就进入了一个维护阶段,这个维护阶段到什么时候结束呢,就是这个软件,比如说下限或者说这个模块完成了被另一个模块所替代,就是它的生命周期终止。
    这个图有什么意义呢?从研发人员的角度来讲,它最重要的意义是有一点,开发阶段其实仅占代码的生命周期极少的时间,但是大家可能会不自觉的认为,有一个点,我们会把维护阶段的成本不自觉的忽视,但实际上维护阶段的成本其实是更高的成本。所以我这里画这个图,最重要的想提一点,开发人员的能力模型里面,我认为其实普通的程序员和比较牛的程序员,他其实在开发阶段的效率很难有很大的差异。比如说,开发人员很普通的可能一个月能完成,牛人他最多,也就是一周能完成,这是很了不起的,但是这个其实是比较弱的差异,有时候你会发现,比较牛的人代码写的比较慢,这个其实并不是说他效率比较低,而是他想的过多,他会想的相对多一点,但是我认为过多其实是必要的成本,因为你如果开发阶段冒失,维护阶段必然付出一定的代价。我认为一个模块开发出去之后,它的模块阶段付出的成本是什么,我会观察那个现象,真正的牛人其实是在维护阶段付出的几乎为零,糟糕的程序猿可能反复在那里改无穷尽的Bug,就是在维护阶段的成本是更高昂的成本。
    1 条回复    2014-11-04 16:01:11 +08:00
    jemygraw
        1
    jemygraw  
       2014-11-04 16:01:11 +08:00
    需求驱动开发是为了保证核心功能的内聚性。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1137 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 18:09 · PVG 02:09 · LAX 10:09 · JFK 13:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.