上下文

有一个带我入行的软件师父,与他喝酒闲聊的时候跟我说过一个事情。手下人员接手了一个大型项目正在如火如荼的开发。他只给这帮弟兄一个要求,那就是把所有的工作事项拆分到3天的工作单位,并进行管理跟进。我的这个师父根本没有任何敏捷的理论概念与实际操作经验,但他有非常清晰的软件管理者常识。这个常识就是拆分,因为软件行业的特点就是这样的。

你如果无法拆分的话,其实你根本不知道怎么干。

所以说为什么要拆分:拆分是管理知识工作的必要手段。知识工作需要面对的太多是无法简单表明进度的场景。不像搬砖,不像流水线,干了多少一看就知道。如果没有拆分,进度管理、风险管理、依赖管理都无从谈起。

敏捷的需求管理过程是需要平衡业务需求方与开发实现方的艺术,但在很多实践中,这种平衡感并不明显。乒乓拆分,就是强化了双方的平衡关系。

在我指导过的团队中,一开始团队不停的在问技巧,手段,思路。但在真正拿出需求进行拆分的时候,我基本不需要给出任何的技巧,手段,思路。其实他们使用已有的知识就能很好的进行拆分了。

类似概念

“乒乓拆分”与传统的需求拆分方法有所不同,强调在需求拆分的过程中,不断在不同角色之间交换视角。类似于一种辩论赛的方式,团队中的业务人员和技术人员轮流对需求进行细化和拆分,最终形成可以进入开发的 板砖 状态需求。

这种方法让人联想到一些类似的概念,如Ping-Pong Pair Programming,在该方法中,两个开发者通过频繁交替角色来编写实现代码测试代码,以提升代码质量和开发效率。同样地,“乒乓拆分”通过交替进行的思维碰撞,确保拆分关键角度(可验证性、平准的粒度)都被考虑到。

关键特征

平衡可验证性与粒度平准,就是两个球拍,待拆分的需求就是那个乒乓球。

概念

可验证性

敏捷的能力从产品的角度来看,就是能够尽早获得市场反馈的能力。这对于习惯于大而全进行设计的IT人员来说却是是一个挑战,因为整个设计的过程是贯穿整个开发的过程,每来一个需求都需要进行一次设计工作。一次制作10个功能,和10个功能一次一次的做,显然第二种方法更费劲一些。但你不能因为一次做一个功能费劲,就不去选择这种方式。可能迭代的一次次的制作从产品角度来说就是非常正确的道路。所以要警惕技术开发人员惯性思维对切分造成的潜在影响。

在指导团队的过程中,很多时候都是略显逼迫技术人员按照业务角度进行切分的。那这种让业务人员参与的一个好处就是,业务人员可以做出一些调整优先级的决策。如果完全是按照技术角度进行切分的话,你只能按照这个切分的思路进行开发过程。往往到后期,业务人员其实是被技术人员绑架了(因为只能这样的交付过程)。这也是业务与技术关系很多时候不太融洽的一个原因(业务的参与感太少了)。

对于敏捷需求的切分,期望的是每一个需求都是制作陶器时手部的一次变化,随着转盘的转动陶器的形状实现了逐渐的变化。手的每一次位置的调整,陶器的形状就发生一次变化,而且这种变化是基于上一次变化。对于软件来说是相似的,软件的每一次需求,都对软件进行了一次调整与改变。每一个需求都是基于上一个需求的一次增量。

这种增量是一种可以被终端用户感知的增量过程,也就是说每一次的需求实现完成,系统就能看到一些变化,如同这个陶器一样。这就是敏捷对需求切分的要求:

敏捷的需求就是粒度小且用户可感知的功能增强。

用户可感知功能增强就是每一个完成的需求从用户角度就能够看出一些变化。

这里就开始介绍下一个概念:

粒度平准

粒度所指的就是需求复杂度,简单来说就是开发人员的工作量。“粒度平准化”概念的来源可以追溯到精益生产中的“均衡生产”(Heijunka)理念。它强调将任务或需求按照一定的粒度进行标准化和均衡化,它不应该太大,也不应该太小,大小应该相对一致。这里不倾向使用 合适粒度(Size appropriated)这个词汇,因为合适这个词汇已经被沙子、板砖和钻石所替代。这里指的是用来干活的板砖需求不应该工作量有数量级的区别(相差10倍以上)。

极度拆分的可能性

问大家一个关于拆分问题:把大象放到冰箱中需要分为几步。同学们会笑着说,分为三步:

  1. 把门打开;2. 推进大象;3. 再关上门。

如果现在要求把“把门打开”的第一步进行拆分的话,你会如何拆分?

  1. 走到冰箱前;2. 用手握住冰箱门;3. 用力拉。

如果把这个第一步再次拆分会是什么?

  1. 抬起眼睛;2. 确定冰箱的位置;3. 迈出第一条腿。

再把这第一步进行拆分,会是什么?

  1. 想着要干的事情;2. 慢慢的抬起头;3. 看向想象中冰箱的位置。

这也就是说,从逻辑的角度其实我们可以无限的拆分下去。如果某人对你说一些需求无法拆分的时候,其实不是可不可以拆分的问题。因为一切的事物我们都可以按照这样的思路进行拆分下去,一直到分子、原子、粒子、夸克等级。就如同对于软件开发的过程,我可以拆分至你所需要写的每一行代码。但一个新的问题就会浮现……

更细的粒度是否有必要

拆分只要过了某个粒度程度,就会有一种没有必要的感觉。这种感觉其实是来自我们对于约定俗成与风险可控性的一种显性的表达。打开冰箱门,需要拆分分解吗?是个人就知道怎么做啊。打开冰箱门有什么风险吗?我做了无数次了啊。

风险来自于:一方面我们以为我们以为的就是我们以为(具备上下文的领域知识,或假设已经具备),另一方面我们过低的预测可能需要面对的风险(对风险的估计不足)。所以我的师父才会强制开发团队拆分成为3天左右规模的需求。这种拆分粒度对于软件项目来说非常重要,但如果拆分更细致的话,比如以小时为单位进行拆分,对于跟踪与记录来说就会存在粒度太细碎的问题。

太小(细碎)的粒度会带来管理成本的提高。因为每一项事情你都需要进行关注,进行管理。太细的粒度会导致管理成本提高。但如果粒度太大或太粗又会造成机会成本的提高。也就是你可能会因为粒度太大反馈速度太慢而造成一些更大的损失。我们需要在机会成本和管理成本之间进行平衡,这样粒度才是合适的。

对于拆的太过细碎的需求,你完全可以打包形成一个单独的需求。这样其实拆小,拆细才是对需求管理的更高要求。

估算就是平准化粒度的手段之一

不管是用什么单位进行估算,哪怕一个时间范围,也是对需求复杂度的一个粒度平准化的尝试。如果你硬要一个实现时间的范围的话,3天左右最多5天工作量的拆分(包括测试工作)。

角色

责任(乒乓拍子)是明确的,两个角色负责确保可验证性与平准粒度。

业务人员

或需求分析人员、产品经理

  • 主要责任: 确保需求的业务价值和可验证性,确认拆分后的需求能够被验证和交付。
  • 具体任务:
    • 初步拆分需求。
    • 验证拆分后需求的可验证性。

研发人员

负责人或关键开发人员

  • 主要责任: 确保需求拆分后的技术可行性和合理粒度,保持实现角度的风险可控。
  • 具体任务:
    • 从技术角度尝试拆分需求,但满足可验证性要求。
    • 验证拆分后需求的的粒度平准性。

过程

拆分的过程,可能发生在需求校准会议之中,也可能发生在平常的需求沟通过程之中。关键点在于要有两个角色参与拆分的过程,一个代表业务方确认可验证性,一个代表技术方确认粒度平准性。团队如果熟练之后,可以进行角色互换。

flowchart TD
start1([开始]) 
end1([结束])
start1 --> b{业务视角}
b -- 拆分 --> 粒度平准后的需求 
b -. 无法拆分 .-> t{技术视角}
t -- 拆分 --> 粒度平准后的需求
粒度平准后的需求 -- 可验证性确认 --> b
粒度平准后的需求 -- 粒度平准确认 --> t
t -- 粒度平准 --> 共同认可
t -. 合并 .-> 粒度平准后的需求
b -- 可验证 --> 共同认可
b -. 有阻碍 .-> 记下待办
t -. 有阻碍 .-> 记下待办
共同认可 --> end1
  1. 触发:识别和准备需求
    • 首先,团队要找出哪些需求需要被拆分。这一步由业务人员主导,因为从沙子需求推进到板砖需求是他们的责任。
  2. 业务角度拆分需求和可验证性确认
    • 业务人员将需求进行拆分,把大的需求分成更小的部分。拆分的目的是确保每个小需求都能通过一些具体的方法来验证,比如用户测试或者业务规则。
  3. 技术角度拆分需求和粒度平准确认
    • 技术人员会评估业务人员拆分出来的需求,看看这些需求从技术角度是否可行,并且工作量是否合适。如果发现问题,他们会对需求进行进一步的细化,确保拆分后的需求不会太大或太小。
  4. 不停重复乒乓的过程(第二步和第三步),持续标记后续工作
    • 对于那些还需要进一步修改或讨论的需求,团队会标记出来,并在会后进行跟进处理。这些需求可能需要额外的文档、技术评估或者与相关人员的沟通。
    • 对于需求明确度状态进行确认,是沙子还是板砖需求。
  5. 结束:双方都确认需求的可验证性和粒度平准性

相关概念

业务拆分锦囊

对于没有任何思路的业务人员可以借鉴以下的拆分方式:

基于AgileLearningLabs的建议(详情见下面参考1)。我们从四个方向下手:

连接词

需求中可能有一些连接词,比如:和……、并且……、当……、如果……、但是……、只要……,甚至是逗号。这些连接词其实就是可以分割的信号,直接尝试进行拆分就可以了。

通用词汇

需求中有很多通用的词汇,比如名词:车辆……、人员……、收据……、记录……、信息……。这些通用的词汇可以被更为精确的词汇进行替代,而且可以被多个精确的词汇进行替换。比如……的车辆、记录……信息的收据。比如动词:维护……、更新……、反馈……、触发……、删除……、等等……。把通用词汇替换成为更为精确的词汇的过程就是拆分的过程。

验收条件

验收条件(Acceptance Criteria)又被称为满意事项(Conditions of Satisfaction),功能完成的标准有哪些?这些验收条件一样是可以切分成一个又一个的增量型需求的。当然不一定一个验收条件切分成一个,也可以一组验收条件成为一个新需求。

时间线分析

假设这个功能实现完毕的话,你将如何去验证这个需求呢?有哪些事件会被你触发?比如登录、输入什么信息之后、点击查询按钮、根据查询到的内容进行几种操作。这种时间点就可以成为切分的思路。再次友情提示一下,如果切得太小了可以打包。

技术拆分锦囊

对于拆分方法来说,有前人进行的总结(参考参考2)。看上去很高级的内容有的时候指导具体工作有些摸不着头脑。在指导无数团队之后,我总结基本有4种方法就可以把需求拆分至我们理想的粒度。这四种方法不是单独使用的,如果接到某个需求,你可以以某种方法为主其他方法为辅的方式进行混合式拆分。

流程与界面

一般的软件应用都会有流程与界面,而且流程与界面就是天生可以被用户感知的单元。所以按照流程与界面进行拆分是拿到任何需求你都应该默认想起的套路招式。在流程与界面的拆分中有三种不同的细节手段:

  1. 步步推进
    • 从流程和界面的角度,分解为画面或流程节点。按照时间的流程顺序,一个画面一个画面的切分所有的流程与画面。制作完成一个画面以及相关交互功能之后,然后推进下一个画面。一块一块的制作。(相对设计与结构比较明确的需求)
    • 例如:登录画面,输出画面,查询画面,维护画面……
  2. 快速验证
    • 软件整体有一个主流程,主流程其实是软件的关键内容。拆分成能够打通各个流程节点,实现主流程贯通的需求,然后逐步增加主流程中的旁支流程。先做薄薄一层,然后逐渐加厚。(需要进行试错与探索的需求)
    • 例如:关键主流程,主流程第一个节点的旁支流程,主流程第二个节点的旁支流程……
  3. 首尾流程
    • 流程中有一个初始流程,一个结束流程,先完成这个初始与结束流程。当用户能够感知到开始与结束之后,再逐渐增加流程之中的内容。先做头做尾,然后逐渐丰富中段。(快速验证方式切分不了的需求)
    • 例如:关键输入+关键输出画面,关键输入画面丰富,关键输入画面之后的第二个流程节点画面……

算法与展现

对于没有明显流程或界面的功能,其实就如同一个黑盒子,有一些输入进,一些输出出。一般这种黑盒子只能控制两个内容:

  1. 控制输入
    • 控制输入变量的数量和取值范围。
    • 例如:
      • 报表中有3种输入变量,默认2项数据,只有一项变量可以调整点击查询按钮。
      • 保费计算中有无数种的车型,先以1年内丰田卡罗拉为输入进行计算。
  2. 控制输出
    • 控制输出的内容和展现出的项目。
    • 例如:
      • 报表中先查询出某些字段,再查询出某些字段(报表中可能因为性能考虑无法实施此拆分方法)。
      • 先展现关键信息,再展现非相关信息。

依赖与层次

如果你面对的软件是有层次与复杂逻辑,也可以使用下面的思路进行尝试:

  1. 逐层推进
    • 用户可能需要触及若干逻辑代码层,才会返回某个结果。这种情况下,可以先让最表层接到用户请求之后直接反馈,然后增加需求所触及的层级。
    • 例如:交换机的若干层TCP协议,可以先切分成第一层协议,然后第一加第二层协议,一二三层协议。
  2. 隔离依赖
    • 对于逻辑复杂的部分,可以把逻辑复杂或依赖的部分进行隔离,再有一个需求打开这个隔离。
    • 例如:依赖某个第三方的算法,算法接口已经明确,但还没有生效。切分成使用明确后的假接口,然后对接真实的接口。

探索与研究

不是所有需求技术人员都知道如何进行拆分和实现的,因为对技术结构的不清楚或实现思路的不确定。都需要有一些探针(技术预研)类的任务先行实施。这种任务有两个关键点:

  1. 必须要求时间盒,也就是说这种任务必须要有时间限制。一天还是两天,甚至是四天。
    • 例如:1个人2天技术探索。
  2. 必须明确这个技术探索任务要解决哪个具体的问题。要求非常明确的定义问题域与结束标准。
    • 例如:明确历史遗留代码中数据库表格调用数量,以及写操作的代码位置

Feature or Epic?

任何敏捷的需求都应该是相对小粒度的,高阶的需求仅仅是为了更好管理这些小粒度需求的分类和标签。当然,最开始的时候可能来源于一个大粒度的需求,一旦经过了拆分,对于不管是Feature(特性)还是 Epic(史诗)都只是细粒度需求的一个标签分类,让我们可以更快速的定位到这些细碎的需求。

这样工作量的汇总也应该是从最小粒度的需求逐渐汇总至需求的标签分类上。不应该存在对feature和epic的早期单独的估算。

一切的决策建议都基于这个最细粒度的需求来进行整体讨论,而不是反向而行之。因为恰恰是这个粒度的需求才会平衡技术与业务的关键粒度,小了大家觉得太细碎了没必要讨论。大于这个粒度,技术的风险和业务的风险不一定能暴露。

原子敏捷性的考虑

“乒乓拆分”方法的核心在于角色之间的视角交替与需求的多次细化,这种多层次的平衡是原子敏捷性的一种具体体现。在需求拆分的过程中,业务方和技术方通过反复交替,将模糊的需求逐步转化为清晰、可验证的任务。

这种方法的成功在于结合了更广阔的视角。通过业务和技术的共同参与,确保最终的拆分能够涵盖所有必要的验证点和技术细节。这种多角度的审视,减少了可能出现的盲点,确保团队能够全面理解和处理需求。让需求拆分,成为一个协作内容,而不是单方的责任。

同时,更强悍的纪律在这一过程中起到了关键作用(责任是明确的,也可以交换)。业务方和技术方在每次视角交替中不断校准需求的粒度和可验证性,确保每个需求的拆分都符合项目的整体目标。

参考

参考1:AgileLearningLabs的拆分建议:

https://www.agilelearninglabs.com/2013/04/introduction-user-stories/

参考2: Agileforall 用户故事拆分参考

https://www.humanizingwork.com/the-humanizing-work-guide-to-splitting-user-stories/