QWS是一款电信交换机产品,其软件部分用C语言开发。经过长期的发展演化,当本文所述的咨询项目开始时,QWS的总体代码量已经超过2000万行,代码库体积超过4GB。本咨询项目所涉及的版本需要新开发的代码量约90万行。

QWS的版本交付团队大致由90名左右开发人员和30名左右测试人员组成。这支交付团队又按特性和模块划分为6个特性团队和2个任务团队,共计8个子项目组。每个项目组分别有一个SVN工作分支,项目组成员将代码提交到分支,项目经理再负责将分支代码合并到主干。

在ThoughtWorks顾问组进入该团队之时,这支多年沿用CMM方法的团队正在自行尝试敏捷方法,刚刚开始第一个为期3周的迭代。但这第一个迭代远非一帆风顺。一方面,由于团队从来没有迭代交付的习惯,开发人员在编码阶段忽视质量,导致提交到SVN的代码有时甚至不能编译,即使编译出软件大包也存在严重功能缺陷,无法进行测试;另一方面,由于团队成员对SVN缺乏了解,多个分支的配置管理遇到了极大的困难。

就在这样一种混乱的状态中,由3名ThoughtWorks咨询师组成的顾问组进驻了这支交付团队,开始对其进行为期4个月的敏捷改造。在项目进展中,我们大量借鉴了源自丰田的精益思想,最终取得了显著的成效。

阅读全文

[zz]Agile Metrics

February 8th, 2010

本文以某大型电信设备提供商与ThoughtWorks合作的案例为基础,介绍如何采用丰田倡导的精益生产方法对大型软件组织进行敏捷改造。在这个咨询项目中,ThoughtWorks咨询师引入的精益理念包括:

  • 5S
  • 自働化
  • 现场管理
  • 湖水和岩石
  • 造物先造人

以这些精益理念结合敏捷实践,贯彻PDCA/SDCA实施策略,在四个月的时间里,成功地对一支超过百人的交付团队完成了初步敏捷改造。

是的,我想要流程改进…

December 20th, 2009

…只要“被改进”的不是我。

到底有多少人怀着这样的念头呢?

给某知名互联网企业做了一个草草的价值流分析。这家企业和同集团的几家姊妹企业最近都在热火朝天地搞敏捷。培训,项目试点,经验分享,宣讲推广,还打算要制定流程规范。一级一级把成果和经验报上去,领导都很支持。业务线的领导说,交付线的同学们多搞搞敏捷,交付能力强了,咱们公司就能更好地应对顾客们的需求了…

等等。这话为什么让我胃里一抽呢?

十分钟画出的价值流图告诉我们,一个用户需求从被客户服务部门收集到,直到成为一个新特性上线供用户使用,lead time总计2个月又20天(约合58个工作日),process time约20个工作日。Muda在这个流程中占65%。

那么交付线到底浪费了多少呢?嗯,交付线的lead time共计17个工作日,process time共计10个工作日。

换句话说,就算这家公司得到了一根魔杖,只要魔杖一挥就能把用户需求变成可用的特性,他们也不可能在两个月内响应用户需求,如果业务线没有“被改进”的觉悟的话。

所有人都在讲流程改进。所有人都在讲敏捷讲精益。你真的准备好了吗?流程改进的结果,真的是你想要的吗?得到一个精益流程所需的决心和勇气,你已经有了吗?

  • Face-to-Face Team
    • 团队成员对开发状态(进度、问题等)缺乏了解
    • 低效沟通导致的步调不一致和延迟
    • 个人工作不聚焦
  • Standups
    • 个人工作与团队目标偏离
    • 因任务受阻而浪费时间
    • 隐藏的、有可能影响项目交付的风险或问题
  • Retrospectives
    • 可以避免的、由于流程低效或缺乏支持造成的浪费和延迟
  • Sustainable Pace
    • 几种缺乏效率的团队工作方式:
      • 任务跟踪不聚焦
      • 任务量不饱满
      • “冲刺”编码(降低质量要求)
      • 任务分配过量
  • User Story Lifecycle
    • 在各个阶段不同角色的工作不饱满
    • 不灵活的计划
    • 时间或工作量严重超出预期
  • Collective Ownership
    • 由于任务需求集中在某人“拥有”的区域而造成的开发延迟(“瓶颈”)
    • 由于关键区域的“拥有者”缺勤而造成的交付风险(“ 巴士因素 ”)
  • Common Vision
    • 各方涉众迭代地汇总观点,就项目的目标、约束和优先级达成共同认识
    • 减少因对问题、方案和优先级的理解冲突而浪费的时间和开发资源
  • Short Releases
    • 在项目进行中频繁交付可工作的软件
    • 减少在制品库存的浪费
    • 降低在制软件不适合生产环境需要的风险
  • Iterative Planning
    • 项目计划根据进展中获得的信息迭代式制定
    • 避免最后关头获知进度或预算超标
    • 减少在低优先级功能上浪费投资
  • Simplicity
    • 尽量消除软件中的浪费、重复和复杂性
    • 降低使用中软件的变化成本和风险(脆弱性)
  • 状态:有缺陷的代码持续产出,软件最基本的功能无法保证
    1. 建立“缺陷发生时自动停线”的自働化机制
    2. 实施可视化管理:停线立即告警,作为最高优先级处理
    3. 解决基础质量问题:消除环境不稳定性,消除伪随机质量问题
    4. 提升团队基础能力:
      1. 采用令牌制提交,明确责任人,谁破坏谁修复
      2. 设立专人负责监控持续集成状态
      3. 对于不能快速解决的问题,预备有效的修改撤销机制,快速恢复生产,减少破坏的影响范围
  • 状态:能得到可用基线,提交失败频率高
    1. 分层分级的配置管理和验证体系
    2. 验证提前:提交代码之前的准入构建
    3. 更严格的令牌制:以成功的准入构建报告申请令牌
  • 状态:主线稳定可用,分支合入主线困难
    1. 标准化的分支持续集成环境
    2. 分支持续集成状态巡检,及时发现问题提供支持
    3. 帮助分支组培养持续集成专门人才
  • 状态:持续集成稳定可用,需要持续提升
    1. 配置管理下的持续集成,解决了改进措施在大团队中复制的难题
    2. 迭代式改善的持续集成
    3. 从“贪多求快”、“一步到位”的建设思路转变,确立“小步走稳”的持续改进路线,将PDCA方法应用于大团队持续集成建设

自动化 vs. 自働化

November 29th, 2009

什么是自动化?是让生产线自动运行起来的技术吗?

那顶多也就是个传送带技术。

《图解丰田生产方式》 说,自働化,是在出现问题时让生产线自动停止

自动停线的自働化,才能在现场现物根据现实找到问题的根因,才能从源头上消除质量问题。只管自动运行不管自动停线的自动化,既无助于发现根因,又不能及时阻止不合格产品的生产,于是生产线末端的检验人员照样不能省。

建立真正的自働化,首先就要改变这个认识。全员意识到,自働化就意味着一旦缺陷发生立即停线,作为最高优先级处理。有了这样的觉悟才能继续前进。

意识之外,自働化的三个必要条件:

  1. 可视化。停线的同时以最直观的方式让所有人警觉,并作为最高优先级处理。
  2. 质量基础。如果设备经常发生异常故障,如果产品经常出现不明原因的质量问题,频繁的自动停线可能直接把生产线打倒。
  3. 能力基础。自动停线之后,团队是否具备快速发现问题、快速恢复生产的能力。

以后回答敏捷的问题…

November 19th, 2009

要做两件事:

  1. 掐表。第一个问题回答完以后,估算整个交流时间还能回答多少个问题,然后请选优先级最高的问。
  2. 回答完一个问题之后,要询问:接下来在这个方面你打算采取什么措施?

没有时间盒、没有计划、没有优先级的交流,没有落实措施的讨论,就是漫议,就是在浪费大家的时间。

敏捷咨询本身首先就应该是敏捷的。

设计问题多于方法问题

November 2nd, 2009

比如说吧,产品和平台之间依赖好严重啊,产品还经常要修改平台的代码;特性组和支撑组之间耦合好紧密啊,支撑组的代码都得到特性组去验证和提交。敏捷怎么解决这些问题啊?还有啊,开发人员总是几个故事一起做,做出来的故事测试人员发现没法测。敏捷怎么解决这些问题啊?

还有啊,架构思想都没有传达到开发人员啊,都做乱掉了;持续集成工具的专家他不属于开发团队啊,出问题找他支持好麻烦啊;测试工具的专家…嗯,最近的一个离我们大概有一千公里吧。敏捷怎么解决这些问题啊?

这些不是方法问题,是设计问题。设计很简单。单一职责,DRY,OCP,依赖倒置,接口隔离,就这么些东西而已。但简单不等于容易。写代码的时候不会设计,划分模块的时候同样不会,划分产品的时候同样不会,管理组织机构的时候还是同样不会。一个软件组织不让员工学会写代码,其结果就是设计问题出现在所有地方。

还有个下半句:管理问题多于能力问题。

我们很想提高工程人员的技术能力啊,应该怎么让他们学习啊?我们这些实践影响的人太少啊,怎么快速复制到成千上万人啊?──想要事情做下去,不走样,就得去关注所有的细节。拍一个任务下去,你周五之前给我完成,我只看结果。完不成怎么样?时间过去了,能力还是没提升,问题还是没解决。这就是所谓粗放式管理。一层一层都说,行,我支持,大家去学习吧──你不去手把手的教着他,他除了变成蘑菇还能变成什么?

管理细节也很简单。代码的坏味道有没有重构?每个函数有没有测试?每次提交的注释是不是符合规范?但简单不等于容易。写代码的时候不会管理细节,做管理也同样不会。一个软件组织不让员工写好代码,其结果就是管理问题出现在所有地方。

持续不能集成

November 1st, 2009

持续集成只是信息源。持续集成的检验是在代码提交之后而非之前进行的,因此持续集成的作用只是使项目健康情况可视化。并且这种可视化必须建立在构建经常成功的前提下。因为软件本身的复杂性决定了只有“是否达到质量要求”能够被简单度量,而“达到(或不达到)质量要求的程度”无法被简单度量。所以,如果构建经常失败,持续集成所能提供的信息就只剩“项目一直不健康”──这个信息的价值很小,如果不是完全没有价值的话。

让持续集成保持经常成功,必须规范三件事:

  1. 提交代码之前必须更新
  2. 提交代码之前必须进行本地验证
  3. 线上构建失败时不得进行任何提交(或更新)

如果做不到这三件事,持续集成就可能降格化为持续不能集成:你知道项目有问题,但不知道问题出在哪儿,也不知道该如何解决这些问题。

为了避免这种降格化,在持续集成到位之后,需要用更多的手段确保三点规范得以落实:

  • 代码库和持续集成分级
  • 责任逐级下压
  • 建立提交前本地构建基础设施

要言之:持续不能集成会使持续集成的价值降低到约等于0(甚至低于0)。要避免持续不能集成的发生,第一要严格规范,第二要提供技术手段使规范能够被落实。

在帮助客户实施敏捷的过程中,ThoughtWorkers常被问到一个问题:有没有一套标准的“敏捷模板”可供快速入门之用?

作为一种强调持续改进的方法学,自然不会有一套放诸四海而皆准的“标准流程”;但对于希望采用敏捷方法的组织和个人而言,若有一组普遍适用的最佳实践作为基础,便能少走许多弯路,以期事半功倍之效。

摆在你面前的,正是这样一本“敏捷入门手册”。

本迷你书从《ThoughtWorks文集》的13 篇文章精选5篇编撰成集。这几篇文章有一个共同点:它们介绍的是一些最根本、最易施行、又最能立竿见影的敏捷实践。藉由这几篇各自独立而又相互关联的文章,我们希望帮助读者从持续集成和测试入手,建立行之有效的项目健康保障体系,并掌握必要的面向对象编程和重构技能,从而切实提升软件质量,并为更进一步的改进打下坚实基础。

如果你喜欢本书,可以 购买原版《ThoughtWorks文集》

或在InfoQ中文站 免费下载这本书(PDF)

博尔赫斯风格的培训

October 16th, 2009

今天培训的主题是,站立会议和回顾会议。

于是,我们先讲,站立会议是干什么用的,应该怎么开,常见的坏味道有哪些,小技巧有哪些。

讲完站立会议,就开始讲回顾会议。大家一起读一遍回顾会议宣言,然后讲回顾会议是干什么用的,应该怎么开。

然后,大家就一起来开一次回顾会议吧。回顾的主题是:我的站立会议。

于是大家开始回顾,各自团队的站立会议开得怎么样,哪些地方做得好,哪些地方可以改进,有什么点子,等等。

一边回顾,一边继续讲解,“这就是回顾会议的要点,大家记下来了吗?”

回顾做完,针对“站立会议讲太多细节”和“团队成员参与度不高”两个最受关注的主题,得到了一系列切实可行的改进措施。

同时,怎么做回顾会议,也就学到手了。

这培训做得,颇有点像博尔赫斯小说的风格。

(还有从 胡凯 那偷学来的小技巧,着实精妙得很啊。)

对象健身操:九诫

October 12th, 2009

  1. 方法只使用一级缩进。
  2. 拒绝使用else关键字。
  3. 封装所有的原生类型和字符串。
  4. 一行代码只有一个“.”运算符。
  5. 不要使用缩写。
  6. 任何类的长度不能超过五十行。
  7. 任何类中的实例变量不能超过两个。
  8. 任何包含容器的类不能再包含其他的成员变量。
  9. 不使用任何Getter/Setter/Property。

阻碍我们写出好代码的,首先是根本不知道代码能写多好。

结构化沟通框架

October 4th, 2009

每次沟通活动(会议)应该有以下元素:

  1. 动机:每个会议应该有且只有一个动机,声明沟通的涉众
  2. 目标:每个会议最好有且只有两个目标,一个针对现状的信息传导,一个针对将来的行动
  3. 实践

例如,standup meeting:

  1. 动机:全团队每天的内部沟通
  2. 目标:
    1. 每个人了解团队整体当前进度
    2. 触发针对问题的后续详细/小范围讨论
  3. 实践:
    1. 每个人讲三件事:昨天做了什么,今天要做什么,重要的事项和问题
    2. 所有人对所有人讲话
    3. 小范围的详细讨论被及时中止并放到会后

再例如retrospective:

  1. 动机:全团队周期性的回顾
  2. 目标:
    1. 增进信心
    2. 促成改进
  3. 实践:
    1. 就事论事,对事不对人
    2. 具体,每个条目只说一件事
    3. 讨论最受关注的条目,每个条目要有后续行动和负责人