# 管理流动
流动抑或单件连续流是丰田生产愿景的基石,单件连续流是一个系统,其中每个为客户创造价值的那一部分在流程中逐步移动,这些步骤既没有等待,也没有批量操作,区别于建立库存的方法,它只有在需要的时候才即时生产。这种连续流将每个流程紧密连接形成全部相连的链,流动一旦停止或发生故障,就没有问题能够隐藏。
# 关注7种类型的浪费
丰田花了大量的时间来完善单件流,在这个完善过程的一个重点部分是消除浪费,同样的思考也可以用在其他领域,让我们来看看精益管理中已经识别出来的浪费:
- 额外的功能特性:根据Standish Group的调查报告,传统的软件开发过程制造了大量人们不需要的功能特性(7% always used,13% often used,16% sometimes used,19% rarely used,45% never used)。每个功能的实现,都要经历软件开发的整个生命周期:需求分析、设计、编码、测试、发布和维护,这需要耗费大量的人力、物力和财力,如果最终人们将不会用到这些功能,那么所有的投入都变成了浪费。而这还没有考虑过多的功能特性带来的系统复杂度所增加的开销。所以额外的功能特性是软件开发过程中最大的浪费。
- 部分完成的工作(存货):在Lean Thinking这本书里面,Mary Poppendieck把制造业的七大浪费之一“存货”对应于软件开发中的需求列表,她这种判断所处的环境是软件需求被写得非常细致,细致到可以直接用于编程的程度,同时这些细化了的需求又不会立马被拿去实现,相反它们会在需求列表中等待相当长的一段时间。当然,毫无疑问这是软件开发中的“存货”之一,然而我认为这并不是全部存货。另外还有一些常见的现象是大部分“已编码完成”的功能不得不等待很长一段时间才会被测试,而被测试了的功能会等待相当长一段时间才拿去被客户验收,这些通通都是软件开发过程中的存货。它们是第二大的浪费。
- 额外的步骤(过度处理):类似的,这种浪费在Lean Thinking中被识别为对需求的过多细化以及不必要的文档工作,我也认同这种说法。同样我也认为这种说法并不全面,因为额外的步骤(过度处理)不仅仅存在于需求中,还存在于代码中。不少程序员会在代码中去做很多“预防性”工作,譬如预见可能发生的变化或者可能出现的情况,为了为这些变数留有余地,结果通常是在代码中写一些额外的代码。这种做法一方面增加了不必要的复杂性,另外一方面如果“可能的”情况永远没有发生,这些代码就成了负债。设计模式的出现可能会让这种问题缓解很多,然而我们还是要处处留意在开发过程中是否进行了过度的处理。
- 寻找信息(上下文切换):在软件开发过程中,经常要找客户确认或者澄清需求,要向开发者传达设计思路和技术要点,要找团队成员了解项目进展情况,要彼此反应遇到的问题以及解决办法等等,总而言之就是干系人之间彼此需要大量的沟通,所有这些沟通都是信息传递的过程,所以及时准确地传达信息是非常重要的。与此同时,开发团队经常面临的境地是很难找到客户进行需求沟通和确认,或者不得不花费很多时间和精力去寻找各种需要的信息,也经常遇到由误解造成的尴尬和浪费。团队用在寻找信息上面的时间,并不直接创造软件的价值,所以是一种浪费,应当努力去减少。我在一些社区中也看到有些人把上下文切换定义为七大浪费之一,仔细思考之后,我认为上下文切换的过程其实也就是及时找到另一类信息,并且进入状态的过程,所以它跟寻找信息的含义是一致的。
- 软件缺陷(Defects):Bug创造价值么?不,没有Bug才是客户所期望的。Bug产生开销么?是,发现Bug、报告Bug、定位Bug、修复Bug、验证Bug等都要花费开销。Bug是可以避免的么?大多数Bug都是可以避免的。所以软件中的缺陷真是彻头彻尾的浪费,如果能采取适当的措施减少Bug的出现,那必定会节省下来很多用来处理Bug的时间,然后把这些时间用在有价值的事情上面,这一正一负会产生巨大的差别。
- 等待:等待也包括让客户等待。无论是客户的等待,还是开发团队内部的互相等待,都是没有价值的事情。等待也会推迟问题的暴露和解决时间,所以减少等待就是减少浪费。
- 移交(Handoffs):据研究一个人若表达能力尚可,大概能表达出70%左右的意思,若对方理解能力尚可,大概能理解70%~80%的意思。若真如此,设想信息从一个人手里传递到另一个人手里,然后再传递到下一个人手里,再往下传,还剩多少了?工作的交接也是一样的道理,经手的人越多,需要交接的地方越多,花费的代价就越高。所以减少交接就是减少浪费。
# 帮助工作流动
看板的核心实践之一是管理工作经过流程每个状态的流动,这意味着要对工作如何流动进行监控度量,同时要确保工作快速流动。可以通过以下几种方式来帮助工作流动:
- 限制在制品。在制品越少,流动越快,团队能发现的改进机会越多。
- 缩短等待时间。避免等待可以采取确保工作总是准备好进入下一阶段的,可以通过计划和拆分工作事项以减少依赖,确保工作项较小且尺寸相近。大工作量难以估算,而且有可能可能也难以暴露。
- 消除阻塞。阻塞术语一种特殊类型的等待,这些事项阻碍了工作进展,但又不受控制,我们要及时跟踪阻塞事项,并及时总结预防阻塞的经验,必要的时候可以通过团队群体行动来一同处理阻塞。
- 避免返工。有时一个缺陷从工作流的一个阶段漏掉,就只能在下一个阶段被发现,这会导致这个工作项的周期延长,内建质量的一个重要实践是缩短取消被引入和解决的时间,如果代码刚开发完成就被测试,而且任何缺陷都在发现后立即修复,就节约了录入缺陷的时间,而且也不用花大量的时间研究缺陷是从哪里引入的了。
- 前置时间目标。可以使用时间盒这种简单技巧,使用固定时间长度的迭代来进行估值计划和检查,来管理风险和聚焦有限完成重要工作。时间盒可以让团队意识到一个任务花了多少时间,并提醒避免过度追求完美而造成浪费。
# 约束理论
系统的吞吐量至少受限于一个约束条件。这也意味着约束减缓了整个系统的生产速度,任何针对高中更快速通过约束的改进都会改善整个系统的运行。我们也可以充分利用瓶颈,确保瓶颈能达到最大容量。瓶颈环节的任何空闲时间都会减少整个系统的产出。
持续改进系统吞吐量有如下5个步骤:
- 识别系统约束。例如,所有工件都要经过一台机器。
- 充分利用约束。例如,确保约束的机器总是在正常运行。
- 使其他工作服务充分利用约束。例如,确保不要将问题工件发往这台机器,这会浪费约束处理问题的时间。
- 打破约束。例如,购买另外一台机器来分担工作。
- 重复。检查整个人系统,看看这还是不是系统中的最大约束,持续改进。
具体充分利用瓶颈可以做如下事情:
- 确保构成瓶颈资源的人或角色总是有工作可做。
- 内建质量确保最小化其工作负荷。
- 消除或至少限制他们的工作被打断。
- 消除影响约束工作的阻碍。
- 精心为瓶颈工作设置优先级,以便团队成员总是在聚焦完成最重要的工作。
- 通过平稳的工作到达速率,使他们处于稳定的工作节奏。