当前位置: 首页 > news >正文

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

\

关键点

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

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

\\

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

\\

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

\\

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

\\

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

\\

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

\\

流动债务是什么?

\\

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

\\

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

\\

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

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

如何计算流动债务?

\\

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

\\
\

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

\
\\

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

\\

偿还流动债务

\\

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

\\

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

\\

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

\\

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

\\

在情境中的指标

\\

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

\\

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

\\

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

\\

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

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

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

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

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

\\

038ccb7658cb6268f4dd45da9c91ed9d.jpg

\\

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

\\\

a6ef61f727e8ef6386c337506a202b4d.jpg

\\

对流动债务的合理使用

\\

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

\\

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

\\

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

\\

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

\\

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

\\

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

\\

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

\\

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

\\

5d1e80f37f254c5c2f682c7cb0aa2292.jpg

\\

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

\\

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

\\

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

\\

a90c2d0807c0d2c4a81c2a00e1913f1d.jpg

\\

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

\\

79daf0b57f6763c14711037e582271f8.jpg

\\

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

\\

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

\\

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

\\

流动债务的不正当使用

\\

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

\\

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

\\

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

\\

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

\\

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

\\

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

\\

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

\\

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

\\

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

\\

a26185854ec04181af840e9f46ccc7dd.jpg

\\

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

\\

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

\\

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

\\

9a1ef57d0953bb2a37dac68775496efb.jpg

\\

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

\\

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

\\

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

\\

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

\\

a24bdc65c7913e199f3d4fdbe66deacc.jpg

\\

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

\\

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

\\

结论

\\

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

\\

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

\\

引用文献

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

作者简介

\\

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

\\\\

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

相关文章:

  • 初学python,感受和C的不同
  • RANSAC 剔除错误匹配 估计模型
  • OpenLDAP在LINUX下的安装说明
  • 快速搭建企业subversion
  • asp.net 2.0 导出DataTable到Excel中
  • PAT 大数运算
  • UVA 11991 - Easy Problem from Rujia Liu?
  • Hadoop概念学习系列之关于hadoop-2.2.0和hadoop2.6.0的winutils.exe、hadoop.dll版本混用(易出错)(四十三)...
  • 蒙哥玛利模幂算法
  • angularjs的$on、$emit、$broadcast
  • Java项目相关监控与调优
  • 非对称加密(RSA、DH密钥交换算法、数字签名)
  • EFM32外设模块—USART V1.00
  • 我的第一篇博客 Javascript继承
  • manila nfs 删除 share 分析
  • Google 是如何开发 Web 框架的
  • 03Go 类型总结
  • Angular 2 DI - IoC DI - 1
  • Java 实战开发之spring、logback配置及chrome开发神器(六)
  • Laravel核心解读--Facades
  • SpingCloudBus整合RabbitMQ
  • 给初学者:JavaScript 中数组操作注意点
  • 解析 Webpack中import、require、按需加载的执行过程
  • 强力优化Rancher k8s中国区的使用体验
  • 设计模式 开闭原则
  • 深度学习入门:10门免费线上课程推荐
  • 深入浅出webpack学习(1)--核心概念
  • 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
  • 使用Envoy 作Sidecar Proxy的微服务模式-4.Prometheus的指标收集
  • 思维导图—你不知道的JavaScript中卷
  • 探索 JS 中的模块化
  • 小程序01:wepy框架整合iview webapp UI
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • ​软考-高级-系统架构设计师教程(清华第2版)【第15章 面向服务架构设计理论与实践(P527~554)-思维导图】​
  • ​软考-高级-系统架构设计师教程(清华第2版)【第1章-绪论-思维导图】​
  • #pragma 指令
  • (1)SpringCloud 整合Python
  • (42)STM32——LCD显示屏实验笔记
  • (ctrl.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (小白学Java)Java简介和基本配置
  • (已解决)什么是vue导航守卫
  • (转)linux下的时间函数使用
  • .bat批处理(七):PC端从手机内复制文件到本地
  • .Net(C#)自定义WinForm控件之小结篇
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • .NET企业级应用架构设计系列之应用服务器
  • @cacheable 是否缓存成功_让我们来学习学习SpringCache分布式缓存,为什么用?
  • [ CTF ]【天格】战队WriteUp- 2022年第三届“网鼎杯”网络安全大赛(青龙组)
  • [1] 平面(Plane)图形的生成算法
  • [android] 请求码和结果码的作用
  • [Angular] 笔记 6:ngStyle
  • [C#7] 1.Tuples(元组)
  • [GN] DP学习笔记板子