写点什么

以流动债务为例论指标的合理使用

  • 2016-12-07
  • 本文字数:6340 字

    阅读完需:约 21 分钟

关键点

  • 流动债务是改进软件开发过程的一个重要指标
  • Cynefin 框架可以像镜头一样,在不同情境下使用不同的指标
  • 我们应该在适当的情境下用上所有指标
  • 可预测性意味着减少可变性
  • 有些情况下减少可变性是好的,有些情况则相反

目前软件开发的一个重大问题是,在需要把软件开发考虑成创建一个基于服务的生态时,却偏偏把它假定为生产一个产品。

软件开发过程和工厂里的生产线之间的关键区别在于,每一个工作项目都解决了一个不同的问题,使之有别于其它的工作项目。软件开发是在构建独特的东西。这种独特性正是一般客户认为的价值所在。

然而,我们看到生产制造的模式被应用到一个软件开发这样的非制造过程中了。在精益生产中已经体现了我们需要消除过程中的可变性的想法。不幸的是,这种想法蔓延到了敏捷软件开发中。我们看到人们在为生产周期(Lead Time,从订货到交货的时间)构建统计过程控制图,以跟进开发过程是否处于控制之下。他们的想法就是:只要我们可以消除变化,工作就可以顺利推进,我们所有的问题就都将得到解决。

可变性是新产品开发过程的天然伙伴。杜绝了可变性就会杜绝创新。我们必须了解产生可变性的具体条件,并管理我们的过程来创造这些条件。我们需要在可变性存在的前提下让开发过程也可以多样化发展。

指标应当在恰当的情况下使用。测量一个复杂的软件开发过程时首先假定它是有序的,那这从根本上就已经错了。

让我们选择流动债务指标作为一个例子来说明指标是怎么被非正当地使用的,也就是说压根没有在它们的适用范围之内。要达到同样的效果,我们也可以使用其它指标,如生产周期的散点图等,但流动债务是一个重要的指标,值得广泛使用。

流动债务是什么?

流动债务是一个先行指标,它给我们提供了一个视图,可以看到交付系统内部正在发生着什么。我们把生产周期定义为“完成时间 - 开始时间”,那么如果为了人为地让处于“进行中”的工作项目数量减少而不得不向其它的进行中的工作项目借用生产周期,那就出现了流动债务。这个词最早出现在 Daniel Vacanti 的优秀著作《可操作的预测性敏捷指标:导论》中。

这里就是一个流动债务的例子。假如说我们只有一个正在进行中的工作项目。如果我们在完成第一个工作项目之前又开始了另一个工作项目,那么我们将有两个正在进行中的项目。如果我们在第一个工作项目完成之前完成了第二个工作项目,那么我们就引入了流动债务。

通常人们引入流动债务的原因有:

  • 阻碍物,即阻碍工作流程继续进行的障碍物。如果我们不想无所事事,那么当我们目前的工作项目受阻时,我们就会再开始一个新的工作项目。
    受阻状态和等待状态之间的区别是什么?让我们用我每天上下班的道路情况来做个类比。道路是工作流程。工作项目就是我的车。每一个交通灯都是工作流程的一部分,也是潜在的等待状态。这样的等待是预料之中的,我总不能把我迟到了的原因归结于交通灯变红了!但如果发生了撞车事故,我的车就会被堵住走不了,这就是阻碍,因为它是意料之外的,它有它特定的原因,解决阻碍也需要做一些工作。在这种情况下,交通警察应该过来帮忙恢复正常的交通流。
  • 一般的策略都会支持多种在制品(WIP),即多任务。多任务意味着同时有多个工作项目一起处于进行中的状态。在现实中我们会不断地阻碍和疏通各个工作项目,以便专心处理另一个进行中的工作项目。
  • 拉动策略的随意使用。一旦决定了将要提交某些工作项目之后,拉动策略决定了将这些工作项目拉入到交付流程中的顺序。在 Kanban 中这样的策略被称为服务分类。但在实际项目中,大部分团队根本不遵循任何拉动策略。他们只是对事件作出反应并暂停某些工作项目,以便为其它“更重要”的工作项目让开道路。除非他们知道为什么要使用一个特定的拉动策略,否则他们会坚持先进先出(FIFO)或先来先服务(FIFS)的策略。
  • 并行工作。有些工作项目只是与其它项目相比更大(根据随机分支抽样的概率项目规模大小定义规模)。虽然我们正在忙于一个大项目,但我们仍然可以并行地完成几个小的工作项目,并因此产生流动债务。

如何计算流动债务?

计算一个给定的报告间隔内的流动债务的方法之一是:

流动债务 = 近似平均生产周期(由 CFD 方法预测)减去已完成项目的实际平均生产周期。

通过这种计算方法,正数意味着我们正在积累流动债务,而负数意味着我们正在支付它。然而,当我们使用它时符号就会反过来,显示流动债务为负。

偿还流动债务

如果你的流程中有许多“人为延长”的进行中的工作项,导致它们的生产周期“比正常时间长”,那对流动债务的偿还就很难具有可预测性。其结果是,你本以为你会对你的平均生产周期很有信心,可实际上却一点都没有。

流动债务是一个可预测性的指标。

可预测性是对未来的状态做出定量预测的能力。在这里,我们把范围缩小一下,专注于估计既定工作项目(功能、项目等)的完成时间。时间预测包括日期范围和发生概率——比如有 85% 的概率少于 3 天。只做预测而不关联概率,那么预测就毫无意义。预测的日期范围越小,可预测性就越大。例如,“生产周期有 85% 的概率会少于 10 天”,这个比“生产周期有 85% 的概率会少于 20 天”更具备可预测性。

可预测性和速度不一样。人们可以预见快速,但也可以预见慢。但只有当我们具备可预测性时,我们才可以开始寻找提高我们的交付速度的方法。

在情境中的指标

在我们追求可预测性时,在高度受限、高度受控的环境中是非常有效的。然而,我们不应该在实践中几乎没有秩序的地方却假设有秩序。在假设有秩序的前提下去衡量一个复杂的软件开发过程是根本错误的。测量标准也应该在情境中考虑。复杂的事务不应该和明显的事务一起测量。要做到这一点,首先,我们需要知道我们正在处理什么类型的问题——有序的、复杂的还是混乱的。Cynefin 框架可以帮助我们做到这一点。

Cynefin 框架是一个意义构建框架。意义建构是人类在多种可能的感官解释和其它输入之间选择的方式,因为他们试图借助现实来确认他们的观点,以便决定或回应他们周围的世界(参考文献 2)。该框架首先是关于语境意识,其次是与情境相应的适当行动。

正如 InfoQ 的文章《适用还是可预见?争取两者都要:可以预见的适应性!》中详细说明的那样,我们创建了两种情境 Cynefin 框架:一个提供给客户,另一个提供给能力(由交付组织的知识、技能和生产能力为代表)情境。

客户需求的不确定性本质为客户的情境定义了 Cynefin 域。我们将只使用三种:

  1. 客户清楚地知道他们需要的是什么。他们已经为这些需求下了定义。(明显的)
  2. 客户知道他们需要什么,但不明确。他们需要一些专家来帮忙分析,以确定它。(复杂的)
  3. 客户只是对他们需要什么有模糊的想法。在最终成为一个定义之前,他们将不得不研究几个备选方案。(庞杂的)

对于开发能力是否与客户需求相匹配的不确定性决定了能力情境的 Cynefin 域。这一次,我们仍然使用三个例子:

  1. 组织有完成这项工作所需要的所有知识和技能。(明显的)
  2. 组织有完成这项工作所需要的部分知识和技能。我们将研究和分析其余的知识和技能,因为会有人在某个地方已经做过了,可供我们借鉴。(复杂的)
  3. 组织完全不具备完成这项工作所需要的知识和技能。我们在此之前没做过这样的工作,我们需要研究各种可能性并学习知识。(庞杂的)

我们通过由域索引的每个 Cynefin 框架将客户的需求进行匹配。由此产生的能力 - 客户矩阵代表了我们将要交付的工作项目的不确定性。

如果某个需求属于一个庞杂域,它会被认为是高度不确定的。如果一个需求属于一个复杂域,它会被认为是中等不确定的。低不确定性在这两个框架中都属于明显的需求。

对流动债务的合理使用

让我们看看一个不错的例子,即信息技术运营团队对流动债务在合适的情境下的使用。他们提供与内部员工和合同工的用户生命周期有关的身份识别和访问管理服务。

我们用上文中讲述的基于 Cynefin 的方法来对服务请求进行分类。

首先,从客户的角度情境化——当客户提出服务需求的时候,他们知道他们真正需要的是什么吗?事实上,在大多数情况下,他们知道他们的需求。他们需要我们提供给他们访问不同的应用的方法。

接下来,从能力的角度情境化——信息技术运营团队知道如何满足服务需求吗?事实上,他们也知道如何满足。根据源自团队知识库的最佳实践,我们可以完成明显的访问配置请求。复杂的请求是通过利用团队内部和外部的专业知识来完成的。很少有要求是庞杂的——这些请求都被转交给另外的专门的团队。

基于以上的情境化工作,我们可以将服务需求归类为低等和中等不确定性。

正如之前提过的 InfoQ 关于可预测的适应性的文章中罗列的那样,明显的问题已经有基于最佳实践的解决方案了。复杂的问题有可预测的解决方案,但需要专业知识来理解,因此有多种好的实践做法。这样,归类为低等和中等的不确定性的工作项目可以在一定的预期下交付。

流动债务是可预测性的一个指标。我们可以在信息技术运营团队的背景下使用它,检查它们是否是可预见的。

他们的交付率可以用下面的累积流图(Cumulative Flow Diagram ,CFD)以图形化的方式展示出来。

X 轴是报告周期内的日期。Y 轴显示在交付过程中的不同状态的工作项目的累积值。工作流用这种方式表示:已经开始的工作的累积数量(橙色带的顶部)和已提交的累计数量(蓝色带的顶部)。为了便于理解,累积流图没有显示未启动的项目,只有已经开始和已经交付的工作项目。蓝色带越陡峭,每天交付的工作项目越多。

但是只从累积流图中,我们看不出工作流是否会比“正常”的预期花费更多时间。

下面的流动债务图则提供了累积流图不能提供的内部信息。时间是在几个星期内。

图表上的红条显示了流动债务的发生时间,绿条显示了流动债务的偿还时间。我们看到这个团队大部分时间都有流动债务。效果在下方的生产周期散点图中可见。

X 轴表示由我们的数据得出的基础过程的时间轴。Y 轴仍然表示的是我们以天为单位的生产周期。

在报告期内,为每一个完成了的工作项目绘制一个点,就产生了散点图。我们通过寻找工作项目完成的日期,并根据它的生产周期的长度在图表上绘制一个点。如果有几个工作项目在同一天完成,并且有相同的生产周期,那么我们就简单地从上到下绘制几个点,把它们叠起来。

通过这样的方法,我们可以推断出他们的生产周期是不可预测的。事实上,他们的客户已经提供了反馈,客户们的访问配置已经被延迟了,因此还损失了业务的生产力,提高了成本。客户对团队提供的服务非常不满,感到生气和沮丧。

流动债务的不正当使用

现在,让我们来研究一个案例。在这个案例中,错误地使用流动债务作为管理决策的基础,这种的情况可能会产生误导,甚至造成破坏。在 2011 年时,有一个提供虚拟招聘的项目——一个聊天机器人,类似于今天的美国陆军"中士的明星",能够在Facebook 的聊天工具中回答问题,比如“MA,你在波士顿有什么java 工作吗?”功能上,也可以实现申请工作、安排面试、支持多种语言等。

使用和上面的信息技术运营团队例子中的同样方法,让我们对项目的需求进行分类。

首先,将从客户的角度情境化——当你的客户要求在Facebook 上实现虚拟招聘机器人的时候,他们真的知道他们要的到底是什么吗?不,他们并不知道。他们对他们的需求只有一个模糊的想法——因此,这是一个庞杂领域的问题。

接下来,将从开发能力的角度情境化——开发团队知道如何在Facebook 上开发虚拟招聘机器人吗?不,他们并不知道。在那个时候,已经有了各种为不同目的而开发的聊天机器人,但在Facebook 上并没有虚拟招聘机器人。同样,那时候也还没有实践过的开发聊天机器人方式,只有许多相互竞争的技术和架构。团队必须选择一种技术并设计架构。这种工作肯定属于庞杂领域。

基于以上的情境化结果,我们可以将大多数的项目工作内容纳入高不确定性的类别中。我们特别要注意,不是所有的工作项目——也就是说是项目范围内的一部分内容——都是高不确定性的。它们当中的许多项都是中等的不确定性,但项目的主体确实是高不确定性的。

软件开发的基本工作就是将一个高不确定性问题从复杂的转变成有序的,并且用一种让它具有可预测性的方式维护它。

这就是为什么我们首先安排高不确定性的工作项目的原因所在。因为我们需要探索解决方案,而且它们可能有很高的概率会对时间安排产生负面影响。但同时,还有很高的概率就是我们可以非常幸运地早于预期时间完成这样的工作项目。我们可以同时采用大量的、一致的、失败的代价可以承受的、细粒度的并行实验,这些将提供反馈让我们知道哪些是可行的,哪些不可行。我们将实验作为一个组合来进行管理。

我们在高不确定性的工作项目结束之后再做低等和中等不确定性的项目。如果不这样做,将意味着我们在试图隐藏不确定性。

下面的累积流图说明了上述内容。还是用相同的方法,工作流程由累计的到达数量(红色带的顶部,正如我们看到的那样,它非常小)和累积的交付数量(蓝色带的顶部)来表示。

交付率为S 型或 Z 型曲线的样子。我们可以看到,最初的交付率很低。这是因为项目刚开始时团队需要首先解决高不确定性的需求,例如通过进行实验来选择要使用的技术和实现的系统架构。这些实验和与它们相关的作决定过程需要耗费大量的时间。在九月中旬,团队成功地将核心问题推进到了复杂的领域内,交付率开始急剧上升。

让我们想象一下,假如项目发起人读过 Daniel Vacanti 的好书《可操作的预测性敏捷指标:导论》。在这本书的启发下,他们决定使用流动债务作为一项指标,看看团队的工作是否具备可预测性,并且最终确保管理方式可以保证该项目的内容被以可预见的方式交付。

如果他们在 9 月 1 日创建了图表,他们会看到下图的内容。

他们会感到震惊,因为流动债务图显示,前三个月实际平均生产周期比“正常”的平均生产周期多差不多四个星期!照这样进行下去的话,赞助商甚至可能会考虑取消该项目,因为它看起来已经完全失控!

当然,他们搞错了,因为他们在完全不了解背景的情况下,就直接使用了流动债务这样的指标。我们现在明白了,如果在不合适的情况下直接使用流动债务去判断项目的进展将是有误导性、甚至破坏性的!

因为我们了解背景我们才会知道,这样的流动债务水平是符合预期的,因为首先被安排的是高不确定性的工作项目,并且作为一种平行地试探性组合在进行。并行式进行的东西从概念上来说就会产生流动债务。正如我们通过 Cynefin 框架看到的我们的管理办法,在项目的开始阶段,就肯定会产生大量的流动债务!

累积流图表明,交付率在九月发生了变化。事实上,正如我们在下面的图中看到,9 月 6 日开始流动债务已经被偿还,团队已经完成了探索并切换到研发阶段,即他们的注意力已经开始集中到中等和低等不确定性的工作项目中了。

之后我们看到,在做中等和低等不确定性工作项目的时候,团队管理的流动债务水平和预期一样。

这个项目确实讲述了一个故事,并且这个故事是一个将巨大的前期不确定性转变成可预测的表现的故事,是一个可预见的适应性的完美例子!

结论

文章的主旨是讲述如何将复杂性理论,尤其是 Cynefin 框架,应用到程序的软件开发过程中。

通过 Cynefin,我们以流动债务作为流动指标的例子,知道了该如何正确地使用指标。

引用文献

  1. Vacanti, Daniel S.:《可操作的预测性敏捷指标:导论》,Daniel S. Vacanti 公司 (2015)
  2. D.J. Snowden, Multi-ontology sense making: a new simplicity in decision making Informatics in Primary Care, 13 (1) (2005), pp. 45–54

作者简介

Dimitar Bakardzhiev是一个在有限支出的情况下成功地管理开发过程的专家。作为一个精益 -Kanban 大学(LKU)认可的 Kanban 教练(AKT)、狂热并专业的 Kanban 实践者和 2015 年度 Brickell Key 奖入围者,在管理复杂的软件项目过程中,Dimitar 将精益原则融入每日的工作中。可以通过 LinkedIn 或 Twitter(@ dimiterbak )联系他。

阅读英文原文 Proper Usage of Metrics with Flow Debt as an Example

2016-12-07 16:451285
用户头像

发布了 152 篇内容, 共 70.3 次阅读, 收获喜欢 64 次。

关注

评论

发布
暂无评论
发现更多内容

稳定性领导者!阿里云获得信通院多项系统稳定性最高级认证

阿里巴巴云原生

阿里云 云原生 可观测 性能压测 获奖

分布式数据对象:超级终端的"全局变量"

科技汇

【IT运维】如何又快又好的进行数据备份?

行云管家

运维 快照 数据备份 IT运维 行云管家

阿里云机器学习PAI开源中文NLP算法框架EasyNLP,助力NLP大模型落地

阿里云大数据AI技术

深度学习 nlp 开源技术

IOS技术分享| ARCallPlus 开源项目(二)

anyRTC开发者

ios 开源 音视频 移动开发 呼叫邀请

为什么 Rust 是 Stack Overflow 最受欢迎语言?

非凸科技

c++ rust 性能 Stack Overflow 内存安全

圈重点!一图读懂OpenHarmony技术日

OpenHarmony开发者

OpenHarmony 技术日

如何完成与龙蜥操作系统的兼容验证,看这里! | 一周动态

OpenAnolis小助手

操作系统 龙蜥社区 一周动态

分享一个JDK批量异步任务工具Completion Service,超好用

华为云开发者联盟

jdk 线程 异步 CompletionService 批量异步任务工具

基于场景文字的多模态融合的图像分类

华为云开发者联盟

计算机视觉 图像分类 场景文本 图像视觉 多模态融合分析

TiFlash 源码阅读(一) TiFlash 存储层概览

PingCAP

深入微服务-SpringCloud调用组件Feign

janyxe

spring Spring Cloud Feign OpenFegin

无聊科技正经事周刊(第4期):理性囤货与人工智能预测

潘大壮

程序员 科技 行业趋势 科技周刊

架构实战营 - 方案设计文档模板

华仔

架构实战营 文档模板 方案设计

Enhanced SWAP内存管理 OpenHarmony构建新的内存管理优化方案——ESWAP

科技汇

解析数仓OLAP函数:ROLLUP、CUBE、GROUPING SETS

华为云开发者联盟

Rollup GaussDB(DWS) cube GROUPING SETS OLAP函数

帮助文档——助客户快速了解您的产品如何使用

小炮

帮助文档

TiDB 查询优化及调优系列(二)TiDB 查询计划简介

PingCAP

小程序自动化测试框架原理剖析

百度Geek说

小程序 百度

面试突击43:lock、tryLock、lockInterruptibly有什么区别?

王磊

Java 面试题

活动报名|OpenHarmony 战“码”先锋,PR征集令

OpenHarmony开发者

OpenHarmony

一文掌握 Docker 技术体系

博文视点Broadview

好的每日站会,应该这么开 | 敏捷开发落地指南

阿里云云效

云计算 阿里云 敏捷开发 研发敏捷 每日站会

浅谈小程序开源业务架构建设之路

百度Geek说

STM32+华为云IOT制作酒驾监控系统:上车就监控

华为云开发者联盟

mqtt stm32 华为云IoT 酒驾 酒驾监控系统

OpenHarmony技术日全面解读3.1 Release版本 系统基础能力再升级

OpenHarmony开发者

OpenHarmony OpenHarmony 3.1 Release

毕业总结

孙强

#架构实战营

等保2.0国家标准是什么?与等保1.0有啥变化?

行云管家

网络安全 等保 等级保护 等保2.0

得物技术浅谈深入浅出的Redis分布式锁

得物技术

redis 分布式 分布式锁 CAP 一致性

短短6小时,AI设计出40000种毒气分子,很多毒性远超战用神经毒剂

图灵教育

AI

不要再焦虑了,进大厂真的没你想象的那么困难

Java架构追梦

Java java面试 后端开发

以流动债务为例论指标的合理使用_精益_Dimitar Bakardzhiev_InfoQ精选文章