浅谈软件项目规模估计——怎么估?

做事所花费的时间总是比你预期的要长,即使你的预期中考虑了侯世达定律。

—— 侯世达,哥德尔、埃舍尔、巴赫

周三的下午,我像平常一样,写着代码听着歌,突然从天而降一份莫名其妙的故事列表,说让我给个人天,用来投标用。作为一个技术异常牛逼的高端程序员,这对我来说岂不是 A Piece Of Shit…哦不,Cake。拿着列表,打眼一看就知道是做什么 — 又是个审批流系统。注册、登录、忘记密码…这些也需要时间?!哦,还要做个SSO,可能要做点数据集成,给个15人天吧!又是一堆CRUD… CRUD 各给2人天一共8个。看起来有4个 Model,乘个4,32个人天差不多。前端还有些工作量,找前端估一下…还有些跟遗留系统集成的部分,这块应该比较麻烦,给个30人天差不多…还要用微服务架构,估计需要一些基础环境,每个组件给3个人天,一共8个组件,算24吧….总共算起来130个开发人天,差不多,再加点buffer,算150吧!差不多了吧…

这一幕是不是有点眼熟?不过,这样的做法可能会带来下面的几个问题:

1. 估计者的估计点数是否能代表团队的估计点数?

问题的答案显而易见。那么有同学会说,此时团队的人员还没完成配置,没办法让真实团队进行功能的估计。确实是这个样子,所以我们只能力所能及的去模拟真实团队进行估计。一般,交付项目的团队肯定不会全上非常有经验的同学,人员配比一定会有 leverage,也就是 Senior 人员和 Junior 人员的比例。所以,在估计的过程中,至少要引入 Junior 的同事,能够从不同经验的角度来看待同样的问题,来使估计不会过分“乐观”。

2. 是否有故事卡片之外的工作时间没有考虑到呢?

上文中的估计看起来是采用的经典的“理想人天”估计法,如果使用这样的估计方法,势必要考虑一些虽然没有在故事卡工作量中,但也一定会花费时间的事务,包括但不限于:

  • 回复电子邮件(沟通成本)
  • 面试(内部耗损)
  • 参加会议(包括内部会议,比如站会、Retro、Code Diff、技术研讨会议、客户沟通会议等)
  • 为当前发布提供支持(上线支持)
  • 培训?(内部的 Session)
  • 任务之间切换/被人打断(程序员出栈入栈的消耗…)
  • 修复bug(一定会有 Bug,一定会花时间修…)
  • 写各种文档(对于对文档比较看重的客户,这一部分会占用不少的时间)

这些事务会伴随整个交付过程中发生,基本上都是正常交付必不可少的工作内容,而且根据笔者的经验,这些事情占据的时间并不比完成故事卡的编码工作要少。

3. 故事卡的需求是否清晰呢?

在项目启动前拿到的故事列表,往往只有 Epic 级别的,也就是很粗粒度的故事卡。故事卡中的 AC(Acceptance Criteria,验收条件)往往只考虑了最简单的 Happy Path,然而大部分项目中(尤其是 ToB项目),Exception 才是相对复杂的,这些异常情况往往需要花费更多的时间完成。在这种情况下进行估计,可想而知,一些隐藏的需求点往往难以发现。

问题可能的答案

那么想要解决上面的问题,或者说更好一点的缓解上述问题的方案是什么呢?《敏捷估计与规划》中介绍了一些基本的方法。

首先,要进行集体估计

集体估计可以缓解因为个人能力不同所引发的单点偏差,不同的开发成员对于某个需求在不同角度的阐述,也容易让大家对需求有更全面的理解,也易于发现潜藏在需求中的风险。阐述的过程中,出现复杂问题时,可以及时联系相应的专家资源。对于一些规模较大的卡片,也可以综合大家的意见,进行更合理的拆解。同时,需要由要做次工作的人来进行估计,这样会产生更多的责任感,可以在一定程度上缓解乐观估计的问题(Lederer and Prasad 1992)。

其次,是方法

《敏捷估计与规划》介绍了2种基本的方法:理想人天法和故事点法。

1. 理想人天法

理想人天法就是直接把故事卡估计成理想人天。所谓理想人天,就是“在需求非常明确的情况下,进行编码、测试工作所花费的时间”。就好像篮球比赛一样,每节12分钟,4节总共48分钟,这是比赛的理想时间。但是谁都知道,一般NBA每场比赛都要2个半小时左右,比赛激烈的话三个小时都有可能,比赛真正持续的时间与理想时间是有较大差距的。相比于篮球比赛,软件项目“场外”的工作就更多了,除了上面问题2列出的那些实务之外,像是方案变更引发的大量沟通、集成联调、测试过程中的需求讲解、项目的交接等等,这些工作也需要算到项目时间之内。同时,对于同一个项目,不同的人根据其能力、经验的不同,会有不同的理想人天。

所以在估计完理想人天之后,如何进行实际人天的换算,在实际应用中,仍然是个大问题,所以…最好就不要用了。

2. 故事点法

故事点法就是按照故事卡的规模和难度,给予每张故事卡一个点数。注意,这里的点数代表的不是所需的人天,而更多的是难度系数。

开发人员因为自己技能、经验、能力的不同,解决同样的问题,所花的时间差别是很大的,但对规模的估计却是一样的。就好比从北京到上海,坐飞机1个多小时,高铁5个小时,步行要…一个月左右吧,距离是一样的,根据不同的速度,会花费不同的时间。

同时,人们一般很难对一个规模进行准确的估计,比如从北京到上海的绝对距离是多少,估计没几个人知道。但是,人们能够比较容易的比较两件事物的差距或者说倍数关系,比如:北京到上海的距离跟从上海到香港的距离是差不多的,这个距离是北京到郑州距离的两倍。所以我们在做估计的时候,可以按照难度系数分成几波,然后在内部在进行一些比较和排序,然后按照比较的差距分配一个规模点数,比如1、2、3、5、8、13。

大家可以看到,这个规模点数并不是连续的数字,而是采用了菲波那切这一个神奇的数列。这样的数列有2个好处,一个是不会出现连续的倍数关系,比如4点的故事卡片是2点故事卡片的2倍;其次是表明出规模越大的卡片,其不确定性也承递增趋势,所以会给更高的点数。

有了故事点数,我们仍然无法判定项目什么时间能够交付,因为缺少一个“速度”,也就是团队的开发速度。如果面对的是一个成熟的团队,并且使用类似的技术栈,且与客户的合作模式基本相同的话,那么可以参考前一个项目的速度,来进行交付时间的计算。但如果面对的是全新的客户、不同的技术栈,以及完全重新配置的团队,那么速度基本是不可估的。这时候,有时候会根据 Tech Lead 和 PM 的(Pai)经(Nao)验(Dai),进行硬估:把每个点数转化成N个人天。比如1个点数需要2个人天,那么100个点数的项目就是200个人天。当然,这种方法…说多了会掉泪。

最后,给项目加些缓冲(Buffer)

一般来说,面对这种情况,本着对客户和我们自己负责的态度,需要给项目加一些缓冲区(Buffer)。Buffer 分两种,一种是功能Buffer,一种是进度 Buffer。

功能缓冲

增加功能 Buffer,简单来说,就是把全部的故事列表进行估计,假设得到总点数是100点;然后按照优先级进行排序,挑出其中的MVP,要少于总量的 70%,作为必须要做(Must Have)的部分。剩下的 30% 作为做了更好、不做也不影响主要功能(Nice To Have)的部分,通过这种方式来缓冲项目里程碑的风险。

进度缓冲

进度 Buffer,是用来缓冲估计之外的异常情况引发的项目时间的拉长。进度 Buffer 根据项目的不确定性的差异,计算的方法和结果会有较大差异,有兴趣可以参考《敏捷规划与估计》,这里就不赘述了。不过根据 Leach(2000)准则提出的建议,至少要保持整个项目的20%以上,否则也许不能为整个项目提供足够的保护。

不是总结的总结

上面的这些方法能一定程度的规避风险,给开发团队带来一定的空间,但过分的强调估计和交付计划的准确性,会带来更深层级的问题:

  1. output over outcome。客户更关注功能列表的完成,而不是产生的业务价值。
  2. 开发团队会倾向于裁剪用户故事的功能,3个点的故事卡,尽量控制在规定时间内完成,即使可以花更多时间把事情做的更好。
  3. 控制需求变更。可以进行需求变更,但这个过程更像是一个异常的情况,而不是喜闻乐见的。
  4. 当我们发现了更好的业务点、idea时候,会倾向于隐瞒,以免额外的业务功能会增加工作量。需求变更往往会涉及客户谈判的事情,尤其是当客户观念是传统的供应商管理策略:我来控制需求的全景,能多做点就多做点。
  5. 在客户合作和谈判的天平上,客户关系会向谈判的方向倾斜。

估计和计划会使团队和客户更多的聚焦在工作量,而不是工作的价值上。如果能够引导客户从 output 导向的思维转变到 outcome 导向上,那么团队就不用再疲于奔命的完成那些并不会用到的feature上,而是可以有更多的时间去提升产品质量,进一步提升业务价值。


更多精彩洞见,请关注微信公众号:思特沃克

Share

浅谈软件项目规模估计——估什么?

预测是一件非常困难的事情,尤其是预测未来。—— 尼尔斯.玻尔

玻尔

定制化软件开发是一件复杂的事情,尤其是目前我们主要提供的端到端软件交付,它极大拓宽了软件开发的生命周期,更加着眼于业务价值,但这也增加了整个设计、分析、交付过程中的复杂度。软件交付已不仅仅是传统意义上的技术交付,更包括了体验设计、业务分析、测试、管理、运维、运营支持、以及流程管理的内容。

基于笔者几年浅薄的软件交付经验,尝试总结在初期进行规模估计的时候,应该考虑的范围会有哪些。

体验设计

在笔者看来,在互联网产品的影响下,目前客户对体验设计的要求已经到了“奢侈”的程度,经常对仅有几十个、甚至几个用户的系统提出很多关于体验式上的较高要求。但人毕竟是视觉动物,好的展示效果、使用体验往往是产品的加分项,能带来比较大的口碑收益。同时,这也是最容易跟客户(尤其是业务客户)产生交流和互动的地方,有利于跟客户的深入沟通,特别是这些终端用户还经常是项目重要的 Stakeholder。

在端到端交付中,设计人员会参与项目的整个交付过程,从最开始的 Discovery 一直到产品的上线,从与客户沟通设计需求,到方案设计、方案确认,再到开发过程中与开发人员、业务人员协同方案落地,从源头到落地保证方案的准确性。

功能性需求

在敏捷软件开发中,系统的业务功能会从终端用户的业务价值交付出发,被拆解为一个个用户故事,形如:

故事卡模板

全部的业务功能会形成一个用户故事列表,来从更细的粒度上描绘业务全景。 这部分是项目规模估计中最重要的一部分。所以业务分析和拆分的整个过程要非常非常非常的仔细,因为初期的这个故事列表很可能会成为对客户的一个承诺,未来如果发现不在故事列表中,但也必须要做的重要支撑功能时,就需要增加跟客户协商谈判的成本,或者默默的认了。

在拆分完成进行复检时,敏捷团队(而不仅仅是BA),可以问自己下面这几个问题:

  • 客户所处的行业是什么?本行业有没有固定的业务领域模型?客户想做的是哪个模型的扩展?
  • 有没有类似的竞品可以参考?
  • 有没有考虑系统交互的全部的用户角色?
  • 有没有系统自动推进、不需要用户交互的任务?
  • 有没有考虑全部的业务场景?正常的场景和异常的场景?
  • 每个场景的每一步是如何对接的?具体的详情是什么?是否可以进行进一步拆分?
  • 每个环节使用的用户数量是多少,会有性能要求么(精确到每个指标)?
  • 系统边界是什么?待开发系统和待集成系统各自完成的业务功能是什么?
  • 是全新的系统,还是需要与旧有系统做数据迁移,逐步替代?是否有逐步替代的计划和方案?

拆分方法可以参考《庖丁解牛:产品需求分析》,在这里就不展开了。

非功能需求

除了功能需求外,非功能需求更要引起重视,这往往是项目容易忽略、掉到坑里的地方。

考虑到我们开发的往往是 Web 或者 Mobile的产品,最基本的,要考虑:

  • 浏览器的兼容性问题:兼容哪些浏览器,兼容版本。
  • 移动端的兼容性问题:兼容哪些手机设备,操作系统,版本号。

除此之外还包括:性能,可维护性,可测试性,可用性,可移植性,可扩展性等,项目太多就不展开了,这里单说下性能。

性能是个比较容易量化的需求,比如同时并发访问的人数、页面读取时间等。对于一些用户量较大、高并发的场景,可能需要做多级的性能调优:从应用代码级别、到数据库级别,再到部署架构级别,甚至CDN缓存级别,都可能成为需要考虑的部分。这部分根据项目的情况不同,差异会很大。有的项目可能并不需要投入太多精力在这上面,只需要对其中明显的性能问题进行一些修复,但有的项目可能整个项目都在满足性能上的要求,所以不可不察。

技术架构

有些项目,客户会比较看重我们对产品架构的设计能力。这个时候,技术架构不仅仅需要简单满足短期项目的诉求,还需要有更长远的规划。在这种情况下,前期 Inception 的时间不能支撑整个项目技术架构的设计和搭建,可能是需要更长时间的设计和演进,这部分可以作为独立的工作来进行估计。部署架构亦然。

开发部署环境

同时,为了能够支撑持续集成/持续交付,整个交付过程往往需要一系列的开发、测试、上线的环境,包括但不限于:CI环境、开发环境、QA环境、SIT环境、UAT环境、Pre-Prod和Prod环境。如果这些没有预先准备好的话,这些环境的准备工作也会花不少时间,尤其是当同时涉及客户内网和外网的情况下,甚至会成为项目的严重风险。

与三方的集成

集成往往不是个小问题。目前的软件项目,往往都是基于现有的系统进行开发,所以集成的工作必不可少。如何进行契约的制定、数据的迁移、其它供应商三方系统开发工作的推进、接口的集成联调等,往往都是项目全周期的工作重点。一定从项目第一天开始就要思考持续集成、持续交付,万不可把这部分工作留到最后处理,血泪经验之谈。

测试

敏捷项目中的测试,跟传统的先开发、再测试的这种方式极为不同的一点是:没有固定的 Tester,而是全员来保证软件的质量。测试包括的范畴也比较广,目前项目中的标配包括了:

  • 自动化测试:单元测试/集成测试/功能测试
  • 迭代内探索性测试
  • 业务回归测试
  • 性能测试
  • 安全测试
  • 代码质量测试

这些测试根据项目规模、复杂度的不同,规模估计上会有较大差距。就比如安全测试,有的系统是面对企业内部用户使用的,仅部署在内网,这样仅实现内部权限控制即可,一般不会有安全问题,安全测试的粒度也可以适当放粗;但有的系统要部署在互联网上,供终端用户使用,此时安全测试不仅仅要考虑应用层面的权限隔离,还要考虑网络层面的防火墙、防攻击策略等。这部分可以由专业的安全专家提供建议方案,看如何合理的将测试任务放到总的规模估计中,并与客户提早达成一致。

验收交接流程

这部分是比较容易忽略的,主要包括了软件的整个验收流程、代码交接、文档撰写工作,根据情况不同,可能会使项目延长1周~4周不等的时间,在项目之初也要考虑到。

总结

在初期进行规模估计绝不是一件容易的事情,需要跟客户的深度沟通,敏锐的洞察力,多角色的思考,以及快速的判断,否则后面。。。

Share

开发与设计中那些共同的隐喻

设计师/产品经理:“他会在万众瞩目中出现, 身披金甲圣衣, 脚踏七彩祥云,咔咔咔把我的设计全部实现!”

引子

偶然跟设计师同事聊天,谈到他们眼中的程序员应该是什么样的。

大叔:“好的程序员不应该三心二意,上来就学很多不同的语言,应该精通一门语言!”

小九:“那设计师会在Photoshop,Pixelmater,Sketch,balsamiq等等这些工具中,只精通一样,而不去学习别的吗?”

大叔:“这不一样,编程语言怎么能跟这些工具相提并论,比如Sketch比较适合快速实现一些Hi-Fi的高保真原型,Photoshop善于处理位图,balsamiq用于画一些Low-Fi的线框图,这些工具都是在不同情境和需求下使用的。”

小九:“我倒觉得这跟编程语言一样一样的。当需要写后台服务端的时候,我们用Java;要快速写工具脚本的时候用Ruby;要写页面交互的时候用Javascript;要写底层高性能代码的时候,用C或者C++。每个语言都有自己的特点,也有自己的使用场景。设计师应该不会说只要精通Photoshop或Sketch,其它工具就不用学了吧。怎么能为了一滴水,而放弃整片海洋!每一种设计工具都有自己独特的魅力,在学习中都会体会到不一样的乐趣 ”

语言/工具 vs 特性

熟悉PS的都知道,Photoshop中有滤镜、蒙版、图层等一系列特性,我们也往往是先学习工具,顺便就学会了这些特性。然而,其实这些特性比工具本身具有更高的复用性。现在几乎任何一款绘图软件,都会带有图层功能。

程序员也一样,往往是从语言开始,来认识语言的特性的。比如我们学习了C++,顺便知道了Template;从Java中知道了Exception的处理方法,从Javascript中知道了闭包,从Scala中知道了Monad等等。这些特性、思想在程序设计中的应用往往要比语言本身更重要。

除了语言,其实还有一些别的,也是程序员和设计师可以类比的。

思维方式

在程序世界里,有3种比较经典的编程范式:面向过程,面向对象和函数式。

  • 面向过程的编程范式,简单的讲就是把一个大的任务拆分成N多个步骤,只要一步步从上到下的实现即可。
  • 面向对象则是把所有程序中的概念都想成是一个个具体的对象,每个对象有自己的属性、行为,每个对象可以完成自己应该完成的一些事情。通过对象间的彼此互动,来完成复杂的功能。
  • 函数式则是更侧重于用数学函数的方式来思考,把现实中的复杂问题转换成各种不同类型的函数,通过数学的思维方式来解决问题。

这是程序员的三种不同的思维方式,而映射到设计师,可以理解成平面设计师习惯的平面思维和工业设计师习惯的立体思维。

模式

程序世界中的设计模式,是前人大量经验的总结,是在实战中形成的一些在面对具有一定共性的问题时所采用的最佳实践。

在产品设计中,也同样有一些模式可以遵守,比如现在的提醒功能,往往会使用内含数字的小红点模式。

再比如说消息通知功能,往往是采用消息中心的模式 。

再比如说一些常用的组件,如输入的文本框,在交互上共有诸如auto suggestion之类的模式。

有了这些模式之后,不管是在做程序设计还是界面设计,都可以有效的降低设计的复杂度。

Clean Code -|- Human Interface Guidelines

大部分情况下,我们不是一个人工作,而是一个团队工作。

作为一个程序员,我可能会阅读、修改团队内任何一个人的代码,这时候一套统一的规范就很重要,而《Clean Code》就是这么一套规范,让我们写出的代码可读性大大提高,便于团队彼此共享编辑代码。

而作为一个设计师,也有这么一套规范,比如iOS中的《Human Interface Guidelines》,或者Android的Material Design,这些规范用于指导我们在做界面设计的时候该如何选择合适的控件,应该有何种样式,如何在界面中合理的布局,并在团队中形成共识,好让大家可以在同一个工程中协调工作。

最后

综合上面说的:看起来程序员和设计师的工作好像差得很远,但其实大家做的事情是有很多相通之处的。细细体味其中的不同,可以填补之前一些unknown unknown的空白,说不定还可以给你现在的工作带来一些新的灵感。


更多精彩洞见,请关注微信公众号:思特沃克

Share

庖丁解牛:产品需求分析

在庄子的《南华经》中有一则寓言。说是有位叫丁的厨师,替梁惠王杀牛,其技法之娴熟,有行云流水一般的顺畅感。惠王就问他为什么有如此高超的技术。他回答说:“臣所喜好的是『道』,早就超越所谓的技术了。最初臣杀牛的时候,眼里看到的都是『完整的牛』;三年之后眼中就再看不到『完整的牛』。到了现在,臣以精神接触,而不用眼睛看牛,视觉感官停止了而精神在活动。按天然的道理,击入牛筋骨的缝隙,顺着筋骨的空洞进刀,依照它本来的构造,牛的筋骨接合的地方,臣都未以刀刃碰到过,而何况是大骨头呢!”

同样的道理。当我们在面对一头牛--复杂的业务需求时,如果不得其构造,不明其法,是不能够很好的拆解的。只有对需求深入了解,按照其本来的构造,在筋骨的缝隙处下刀,才能拆出不错的用户故事。今天在这里,就给大家介绍一些解牛之法。非『道』,唯术尔。

工作流系统

我们平时经常会接触到工作流类的系统。所谓工作流,就是我在完成一件工作的过程中,需要经过多个步骤,可能还会有多个不同的角色参与。对于这种系统,我们一般有两种方式 —— 横切和纵切。

1、横切

所谓横切,就是先切分出工作流中核心且轻薄的一层,然后再去实现各个步骤中的细节部分。这对于那些核心业务逻辑比较简单、但每个步骤的附属功能多且复杂的工作流系统来说比较适用。

(横切示例)

举个例子:

假如现在我们需要做一个商旅订票系统,其简化的订票流程如下图所示:

(携程商旅的工作流案例)

在这个流程中,每个步骤都包含了很多个功能。比如“会员查找需要预定的航班”这一步,会员的需求可能会包含:

  • 根据起始城市搜索航班
  • 根据选择的城市,找出最近的机场所在城市
  • 使用GPS定位所在城市
  • 翻转起止城市
  • 根据航班号选择航班

如果采用横切的话,我们仅会选取让本流程可以工作的最小故事集,如

  • 根据起始城市搜索航班

甚至,在本故事中,我们可以设置会员仅能通过精确输入起落地城市名称的方式,来进行航班搜索,在不影响本步骤走通的情况下,来最小化这个步骤的工作量。其它的流程也使用同样的策略,来加速打通整个业务流程。

横切的优势在于可以快速实现核心逻辑,并快速上线,验证假设并收集反馈,可以根据反馈的结果来决定每个步骤中的功能应该如何设计、优先级是什么,来避免一些可能出现的浪费。缺点在于整个工作流设计会采用短平快的原则,用户体验较差。

2、纵切

另一种方式是纵切。纵切就是按照工作流中的每一个步骤进行切分,这样可以使每一个步骤都具有相对完善的功能,这在某些需要关注终端用户交互体验的产品中应用较多。注意,这里有个技巧:如果在整个工作流中,需要跟终端用户进行交互的功能仅出现在某几步中,如第一步和最后一步,而中间的N-2步都是后台流程,在开发中,我们可以先实现第一步和最后一步的功能,而中间的流程处理环节,仍然采用逐步线上化的方式,这样可以使整个工作流系统最快的上线,同时能平衡用户的交互体验。

(纵切)

比如上面携程商旅订票系统的例子,我们可以把涉及终端用户操作的步骤:

  • 会员查找航班
  • 会员发起订票申请
  • 公司审批人审批订票申请
  • 会员收到订票成功通知

把这几个步骤拆出来优先实现,及早上线;而中间的跟票务相关的步骤,仍然采用线下的形式。比如工作人员在携程商旅后台,把订单导出到excel表中,人肉打电话给票代,再把票代确定的订票信息填入系统,然后手动通知会员。这种方式对于一些流程复杂但用户量较小的初创公司比较适用,可以在保证用户体验的情况下,大大提升产品上线速度,并降低试错成本。

在这里要注意的是,不管是横切还是纵切,工作流中的每一个步骤都会遵循80/20法则,也就是20%的功能决定了这个步骤的核心价值,而80%的功能仅仅是锦上添花的,所以我们需要更深刻地研究客户的真正需求是什么,提炼出这20%的业务价值到底在哪里,从而进行更加合理的拆分。

功能模块拆分

对于已经拆出的功能模块,仍然可以根据一些方法进行进一步的拆分,这里介绍三个方法。

1、按业务规则拆分

同样的流程和操作,由于输入的数据业务规则不同,因此进行数据处理时采用的方式也不同。对于这样的情况,我们可以把功能按照业务规则来进行拆分。

典型的例子是搜索引擎,比如Google。在Google中,输入框只有一个,但Google会根据你所输入的数据规则的不同,来进行不同的处理操作。看下面几种情况:

  • 在Google搜索框中输入一个关键字,得到这个关键字相关的搜索结果
  • 在Google搜索框中输入一个算式,如“ 1+1=”,得到算式的结果
  • 在Google搜索矿中输入“ThoughtWorks site:www.example.com”,得到在www.example.com这个站点中出现ThoughtWorks的页面

对于这样的情况,我们可以把每一个业务规则都单独拆分成一个用户故事。当然,虽然这些用户故事看起来很相似,但是大部分情况下,这些规则的优先级是截然不同的。总会有一簇最高优先级的用户故事以及围绕在外围的用户故事。比如在这个例子中,对于Google来说,支持关键字搜索一定是最高优先级的,需要在产品设计的一开始就要实现,而能够计算算式的,可能很多年之后,才开始考虑加这样一个功能。

2、1+N模式

第二种情况,是对同样一个流程,在终端接不同的网关或渠道。最典型的例子是在线支付。比如,我在京东上买了一盒磁力橡皮泥,提交订单进入支付流程,在支付页面可以选择微信支付、京东支付、银行卡支付等等。

第一次实现支付的功能,可能会比较复杂,但后面如果从一种扩充到多种支付方式,就相对比较简单。而且最先需要支持什么样的支付方式,你可能在一开始也拿不定主意。这个时候,我们不妨将支付功能拆成2张卡,形如

  • 会员可以使用微信支付/京东支付/网银支付中的一种进行支付
  • 会员可以使用微信支付/京东支付/网银支付三种渠道进行支付

使用这种拆分方法,可以延迟决策-我们需要最先支持哪种支付方式,同时合理的评估项目的工作量。

3、复杂的业务模型拆分

对于有的系统,业务模型可能会非常复杂,比如一个房产交易平台中的房产信息,可能包含户型信息、中介信息、地理位置信息、价格及购买相关的税率信息、展示图、效果动画等等,当我们需要在系统中引入这样一个业务模型时,如果一上来就要考虑清楚这个业务模型的方方面面,是个性价比很低的事情——做了很多功课,但没有给客户带来真正的业务价值。

这个时候,我们需要将业务模型,按照我们实际需要提供的功能进行拆分。比如,我们要做一个中介搜索系统,可以仅取出模型中的中介信息,而不需要处理其它部分。即使我们需要整个业务模型去做一些事情,也可以把其拆成一个个子模型,根据子模型的业务价值及优先级去设计相应的功能。

比如在这个例子中,我们需要对房产的信息做展示

  • 对于户型信息,需要有户型图,户型相关的文案展示
  • 对于中介信息,可以看到中介人的头像、联系方式,可以使用多种方式在线联系中介代理
  • 对于地理信息,我可以在Google Map上查看其地理位置,并能够从我的位置导航过去
  • 对于展示的图片和动画,我需要像幻灯片一样,可以在页面上播放
  • ……

那么,如果我们一开始就着手于解析这个房产业务模型,那可能浪费了很多时间,而没有交付对用户有价值的业务功能。这个时候,我们需要区分哪些信息是核心信息,是对用户来说最有价值的,把这些信息从业务模型中提取出来,而后设计相应的更小的业务功能,切忌一蹴而就。

需求拆分是否有一套完美的方法?

需求拆分是没有银弹的,要根据具体的场景、限制来选择合适的拆分方法。在遇到使用某个拆分方法,不能满足当前业务需求时,看看是不是可以换个思路,换个方法。

当然,在选择拆分方法时,也有一些技巧,如

  • 基于80/20法则,选择那些可以拆出低优先级卡片(或者可以被扔掉的卡片)的拆卡法。
  • 选择可以把卡片拆的大小差不多的方法,未来在发布计划中更容易做需求置换
  • 选择开发团队更容易理解和实现的方式

当然,这一定不全面,每个人在不同的场景、限制条件下,都会有不同的技巧。相信你自己的拆分方法,多与团队成员沟通才是不变的法门。

以终为始-故事验收方法

Bill Wake提出了一个好用户故事的验收标准——INVEST模型,它由六个单词的首字母组成,分别是

  • Independent:每个用户故事应该是独立的,不会和其他用户故事产生耦合
  • Negotiable:并不会非常明确的阐述功能,细节应带到开发阶段跟程序员、客户来共同商议
  • Valuable:每一个用户故事的交付都要能够给用户带来用户价值
  • Estimable:不需要能够准确的估计,但需要能辅助客户排定优先级
  • Small:要小一点,但不是越小越好,要大小合适,可以更容易的圈定故事范围
  • Testable:需要能够进行验收测试,最好能把Test Case提前加进去

这不仅仅是故事的验收原则,更是在进行需求拆分的时候所需要考虑的拆分原则。当然,凡事有例外。在需求拆分中,有时会拆出一些实在不能满足INVEST原则的故事卡片,也不要太纠结,我们追求完美,但也总要接受现实的不完美。这个时候,跟开发团队多交流,开拓思路,协调一个比较好的拆分方式,比自己一个人憋大招要好的多。

最后

再介绍几个反模式。

  • 按照技术架构分层进行拆分,常见的会按照持久层、应用层、展示层进行拆分。这种拆分方式拆出来的用户故事,会明显破坏INVEST中的Valuable的原则,而且各个故事卡由于各方面的原因,如开发进度不统一,无法灵活的集成上线。
  • 拆分时,把复杂的UI交互算在故事卡片中。大部分情况下,比较fancy的UI交互都不是核心的业务功能,这部分功能可以作为用户体验优化的卡片,独立拆出来。
  • 拆分时,过早考虑性能问题。在性能基本达标、不出现大问题的情况下,提升性能很多情况下也属于用户体验的一部分,可以单独拆出来,左右优化卡片。
  • 拆出一些管理类的卡片。比如管理产品,实际上可能包含很多产品相关的操作,如导入、编辑、同步信息、改变状态、上架、下架等,所以应该根据具体的功能,拆分成更为准确和大小合适的故事卡片。

欧阳修在《卖油翁》中,提到一个老翁,在倒油时能通过铜钱中心的方孔,却不洒一滴油,大家都很惊叹,他只说了一句话——“无他,但手熟尔”。需求拆分也一样,并没有什么高深的学问,拆的次数多了,也便有了那份手熟。


更多精彩洞见,请关注微信公众号:思特沃克

Share