第二章 过程改进,没有灵丹妙药
第二节 2004年10月1日:“精益:比五香熏牛肉还好”
等待
第四个极度浪费是等待。前面谈到的运输问题只涵盖了创建、分支集成和及时沟通方面存在的一大部分等待问题。但等待远远不止这些地方。最常见的盲区是,团队在功能的优先次序上达不成一致,或者即使达成了一致但没按照既定的顺序去实施。也就是说,项目经理如果胡乱地写规范书,开发人员就不得不等待;如果开发人员胡乱写代码,则测试人员只能等待;如果测试人员胡乱测试,那么所有人都必须等待。
极限编程、敏捷方法和团队软件过程都强调要求团队确定一个统一的工作次序,并且得到客户或者负责人的认可,然后再按照这个顺序依次开展工作,直到他们决定重新审定工作次序为止。团队软件过程在这方面尤为严格,但如果没有一个临机应变的带头人,这样做也不会有可持续性。
此外,不稳定的代码也会导致等待。只要代码不稳定,测试团队就不得不等待,就像其他需要等待用户反馈的事情一样。极限编程和敏捷方法特别注重经得起考验的稳定代码,这是深度优先策略的又一个要点。
作者注:其他形式的等待是因为部署新的服务或有其他类似事件的发生,整个服务系统环境需要稳定化或进行同步。一种避免浪费这种等待时间的最好方法是公开操作过程,并逐步更新部署。我将在本章后面的专栏“生产第一”中讨论这个内容。
过度开发
第五个极度浪费是开发过度。你会经常遇到这样一种情况:编制过于复杂的功能,在已经运行良好或并不称得上瓶颈问题之处对性能要求过于吹毛求疵。这种浪费跟过量生产有关,但这里更强调在具体功能的实现上面。
药方:测试驱动开发。这是一种为实现既定设计方案的极限编程及敏捷开发方法,它在实现了单元测试的同时实现了代码全覆盖,一石二鸟。其过程相当地简单:
1.创建API或者公共类方法。
作者注:这是我和敏捷社区的一些成员起争执的一个地方。你是在写单元测试之前还是之后写API或者公共类方法?偏执狂说之后写,但我认为要之前写。两者不同之处在于,前期方案设计的工作量,以及你的代码依赖方与你之间的关系。我会在其他栏目再次谈及前期方案设计,我相信,在10万行代码级别的项目中适度的前期方案设计是成功的关键要素。
2.按需求写一个API或类的单元测试。
3.编译并创建你的程序,然后运行单元测试并确认它失败。(如果成功了,则跳过第4步。)
4.不断修改代码直至其通过为止。(同时要保证以前所有的单元仍然能够测试通过。)
5.重复第2步至第4步,直到所有符合需求的API或者类都测试通过。
很自然,当你掌握了这种方法的窍门之后,你可以一次为多个需求写多个单元测试。但当你刚刚起步的时候,最好还是一次只做一个。这样能够养成良好的习惯。
当你使用测试驱动开发方法时,你就不必写过多的代码。你也自然而然地得到了很容易测试的代码,并且这些代码通常还是高内聚、低耦合、少冗余的——所有这些都是真正的好东西。哦,我曾提到你也能获得代码全覆盖的单元测试了吗?你还有什么不满意的吗?
库存
第六个极度浪费是没有交付的工作产品。这跟削减功能有关,但它也包括那些正在进展中的工作。当你采取宽度优先的开发方法时,你所有的工作同时开展,直到代码编写完成并完成稳定化。所有完成的规范书、设计和等待通过测试的代码都属于库存。它们的价值都尚未实现。
尚未实现的价值是种浪费,因为你不能把价值演示给客户和合作伙伴看。你不能得到他们的反馈。你不能改进和优化客户的价值流。甚至,如果产品计划改变了,这些尚未实现的库存通常就变成了巨大的工作浪费。
精益拉模型强调只做需要做的事情,因此它的结果就是低库存,这在Scrum和测试驱动开发方法中得到了很好的验证。Scrum特别关注正在进展中的工作,时时跟踪并努力减少浪费。Scrum同时注重于定期改进和优化你传递价值的方式。测试驱动开发方法要求你只实现满足需求的代码,多则无益。
质量缺陷
第七个极度浪费是返工。这是最明显的一个,也是我过去批判得最多的一个(参见第5章)。极限编程和敏捷方法通过各种方法来减少Bug和返工,这些方法不仅仅包括测试驱动开发、每日创建、持续的代码复审和设计复审,等等。
然而,极限编程和敏捷方法也以一种更为微妙的方法来减少Bug——在边干边学中建立起一种框架。在你为整个产品完成设计和编码之前,通过深度优先开发方法,一步步勾勒出整个项目的整体框架。这避免了严重的架构问题:这种架构问题隐藏得很深,等到被发现的时候已经太晚,不容许再调整了。听起来很熟悉吧?
减少缺陷是团队软件过程的专长。使用这种方法的团队能够使他们的Bug率下降到行业平均水平的千分之一。第5章的“软件发展之路——从手工艺到工程”会详细论述如何通过团队软件过程进行缺陷预测、跟踪、消除。虽然团队软件过程本质上来说不是精益,但它也并不排斥深度优先的开发方法。
合作共生
下面我该激怒极限编程、敏捷方法和团队软件过程的虔诚追随者了。因为没有理由认为对这些方法的综合运用会比简单地将它们合并的效果更差。使用Scrum来完成一个精益、深度优先、灵活、优化的开发计划。使用测试驱动开发方法来创建一个精益实现。使用团队软件过程来分析你的缺陷和工作,这将大大减少你的Bug及无谓劳动。这些在某些人听起来可能会怪怪的,但在我看来却是再合理不过的了。
现在我如果能找到一些纯正的五香熏牛肉就好了。
作者注:我在纽约长大。在雷德蒙很难找到纯正的五香熏牛肉了。