It's all about
connecting the dots

《精益软件度量》摘记

最近刚看完的一本书《精益软件度量——实践者的观察与思考》(人民邮电出版社,作者:张松),这一块属于之前不怎么涉及的地方,所以有很多地方值得摘抄记录下。需要说明的是,下面的内容是对我自己觉得适合回顾的内容做的摘抄,并不是对原书内容做的目录性质的概要总结,所以不会面面俱到,只是摘录了自己感兴趣的内容。

阅读方法提示:不要从头到尾逐文字地阅读,下文中我已经把关键的句子用黑体加粗了,你可以只阅读这些黑色加粗文案,如果觉得不需要了解前后上下文就直接跳到下一处黑色加粗文案,如果觉得想看下前后的上下文再前后阅读一下,通过这种方式阅读会比较高效

好了,以下为摘抄内容。

原书第一章:度量谜题

按照IEEE(The Institute of Electrical and Electronics Engineers, 1990)的定义,“软件工程是将系统化、规则、以及可控的体系方法,应用于软件设计、开发、操作和维护;换言之,即工程理念在软件中的贯彻。”看上去很美,不是吗?当我们看到一个又一个软件开发组织,特别是大型的组织,特别是拥有辉煌历史的组织,把过程可控作为主要的管理目标时,一次又一次地惊讶于人们是如此容易被误导,而我自己在开发管理的日常工作中,软件工程那些条条框框所带来的虚假的安全感,也曾使我一次又一次地迷失于其中。反思之后,我现在不得不重新审视软件开发的目标和软件工程方法的目的。

可控应该只是我们在软件开发管理中期望优化的属性之一,而不是全部。退一步讲,奥运会的口号或许比IEEE的定义更好地诠释了我们的目标——“更快,更高,更强”,还有一句俗话——“多、快、好、省”,我感觉也比IEEE的那句话更全面。但是为什么人们的注意力都放在了可控性上呢?虽然可控的生产过程可以帮助管理人员更有针对性地优化和改进。不过在向“多、快、好、省”的方向前进的过程中,管理层和项目管理人员的避险本能,在相当程度上扭曲了我们的注意力,有意无意地遗失了原始的目标

原书第4.6节:指标体系需要演进

度量体系中的指标不是一成不变的,所谓“流水不腐,户枢不蠹,动也”。企业内部和外部的变化不可避免,我们设计体系时所期望满足的目标和优先级也可能发生变化,因而需要随之增加、减少或是修改当前的指标。当增加一个指标的时候,一定要记住重新审视一下已有的指标,看看是否有可以减去的,否则指标体系将会越来越沉重,体系的投资回报逐渐降低

说道演进,我们在不同公司,特别是比较大型的公司,看到的现象经常是只增不减。当遇到一个需要从流程角度来解决的问题时,流程人员就会尝试在流程上增加新的内容,或者增加新的流程活动,或是启用新的指标,以减小该类问题发生的可能性。随着时间的流逝,流程和指标变得越来越复杂,由于执行贯彻的难度和成本已经使其成为正常运转的枷锁,整套体系形同虚设,最后就没什么人会再关心什么是真地被落实了

原书第6.1节:识别和拆分高价值特性

较大的需求粒度和交付批量会带来一系列潜在的问题。

  • 首先是“绑架”高价值特性。如果较低价值特性被延误,也会拖着同一批次里高价值的特性,一起延误。
  • 然后还会导致高价值特性很难“夹塞”。从交付价值上讲,排队夹塞不一定是一件坏事。环境会发生变化,团队也会由于获得了更多的信息和知识而改变先前的判断,这些不可避免的因素都可能导致在交付过程中发现更高价值特性,插队行为在大粒度、大批量的交付模式下,要么 会导致项目的延误,要么导致半成品非废弃,会带来大量的浪费。

原书第6.4.2节:发布后——验证价值

如果说由于安全的原因,不想把软件的使用行为告诉Google(用户数据是通过Google的服务来收集和存放的),可以通过自己部署的收费或开源的系统,在企业内网上收集软件和软件特性的使用情况。开源软件Pisik(http://piwik.org/)或Open Web Analytics(http://www.openwebanalytics.com/)就是不错选择。开源的一个好处就是可以根据自己的需要和待分析产品的特点,量身定做信息的收集和报表呈现方式。

原书第8.3.3节:故事点(Story Point)

推荐使用斐波那契数列(Fibonacci)来记录估算的结果(1、2、3、5、8、13……),斐波拉契数列的分布体现了一个经验性的估算模式,估算对象越大越复杂,估算中可能被遗漏的工作量和复杂度细节就越多,估算的准确度越低,因此,更大的数字间距,反映了这种不确定性的增加。

原书第9.2.2节:优化系统的结构

精益组织里通过全功能团队来减少团队和团队之间,部门和部门之间的队列和瓶颈,通过培养多技能人才来解决角色和角色之间的队列和瓶颈。由于信息沟通的效率和信任感等问题,跨团队协作的场景下人们对瓶颈通常不太敏感,也就是说,人们一般是不会太在意其他团队出现的瓶颈的。而全功能团队是指在一个团队里包含不同角色,具备端到端的交付特性的能力。

全功能团队意味着各个工作环节之间的信完全透明,可以轻松识别当中可能存在的瓶颈,并且,如果一个团队中的大多数成员具备能力,可以在系统分析、设计、开发、编写自动化测试脚本等活动之间承担不同的活动,不同工作环节之间出现瓶颈的机会就能降低到很低的水平。在大型产品的开发里,可能由于技术跨度大,也可能是领域知识复杂,全功能团队和通用人才似乎是可望而不可及的,如果改善这种情况,在后面的“第12章 能力-学习型组织”里会有讨论。

速率瓶颈主要通过观察库存来发现。库存是掩盖过程中瓶颈的缓冲,已分析未设计、已设计未编码、已编码未测试的特性都有可能最终不会被发布到生产环境之上,因而成为浪费,不创造价值。专注于将最重要的特性推到“可发布状态”是提高效率的关键之一。

原书第9.2.3节:减少浪费

说到效率,我们一方面关心把事情搞定的速度,另一方面则关心的是我们干的事情到底有没有产生价值。当软件开发的规模较小的时候,不直接增加价值的活动还不太明显。我不止一次地听到一些参与产品初创阶段的资深员工感叹道,“当年我们几个人就把产品搞定了,哪里有现在这么多乱七八糟的事情,那时候每个人什么都能干,效率简直跟现在是不可同日而语的。”这也难怪他们有这样的感慨,虽然这些能够在市场上成功推出产品的人,一般能力确实都很不错。不过随着产品的演进和多样化,软件的规模会急剧扩张。根据Brooks的《人月神话》和Weinberg的《质量·软件·管理-系统思路》,开发工作量的增长不是随规模线性增长的,而是呈几何级数增长的。这种工作量增长的来源可能是软件当中的分支、耦合数量,也可能是人员、团队之间所需的沟通渠道量和信息量。这些系统和组织复杂度带来的额外工作量很难完全避免,但我们观察到,很多软件交付组织在这方面都有不小的优化空间。

……

在不少组织里都存在着一些救火英雄。交付期限来临的时候,我们经常能见到他们忙碌的身影,他们在定位、解决上面那些问题的时候,总是能发挥超人的效果。项目在他们没日没夜的努力下,跌跌撞撞,总是能在最后一分钟(勉强)成功上线。很多公司总是非常认可这些项目的解救者,这里我绝对不想否认他们的敬业和能力,不过还有一句老话叫“善战者无赫赫之功”,当开发人员和团队把事情理得很顺的时候,救火英雄可能是个不需要存在的角色。

……

对于中断和切换,有很多心理学研究指出,当我们有多个任务要做的时候,顺序地把注意力集中于单个任务,完成一个再做另一个,得到的效率一般都比试图并行地在多个任务之间切换效率要高。

……

在Tom De Macro和Timothy Lister的《人件》一书中用了一个E-因子来评估团队成员的有效工作时间,计算公式 是:E-因子=不被打扰的时间/体力出勤的时间。书中认为E-因子是对于员工能否经常在高效的顺流状态非常关键:“在一心一意动脑筋工作的时候,人们在意识上处于一丈红心理学家称为顺流(Flow)的状态。顺流是一种陷入沉思的状态。在这种状态下,有一种精神欢快的轻松意识,一种大部分情况下都感觉不到时间在流逝的意识”。虽然书中没有详细描述如何统计不被打扰的时间,不过大致可以从时间和频率两个角度出发,得到类似的数据。

原书第9.2.4节:关于浪费的小结

在人力成本日益高昂的今天,我们发现的一件有趣的事情,经常是业务部门非常关注如何用计算机硬件和软件换取人的时间,与此相对应的是,软件开发部门经常倾向于用人力填补空缺,而对将手工工作自动化的投入,对通过技术手段减小工作量,则非常保守。

原书第10章:内部质量

“唯一的现实存于我们的内在。让大多数人生活得如此虚伪和没有价值的原因,是他们错误地把外在形象看作现实,却从不允许内在世界发言。” ——赫尔曼·黑塞(1877~1962)

……

根据ISO/IEC 25010的软件产品质量模型,软件产品可以分为8个属性,在每个属性下面还有子属性:

  1. 功能性;
  2. 效率;
  3. 兼容性;
  4. 可用性;
  5. 可靠性;
  6. 安全性;
  7. 维护性;
  8. 可移植性。

……

提升内部质量的动力来源于:

  1. 对于生命周期较长的产品,降低其持续开发的成本;
  2. 对于当前版本来说,提高开发进度的可靠性,降低后端测试周期长度和工作量的不确定性。

原书第10.1.2节:技术债的常见形式

技术债的常见形式

  • 没有重构的代码。
  • 未达目标的架构和设计决策。
  • 未能更新的依赖。
  • 缺乏自动化测试保护的代码。

……

3. 未能更新的依赖

在开发的过程中,软件所依赖的平台、框架、软件库可能随时出现更新,诸如数据库、编译库、JDK之类的厂商技术平台如果进行了升级,当我们知道未来肯定要部署到新的平台上的时候,经常会为了升级过程中要面临的兼容性问题而踌躇,很多人会决定为了保持现有的进度,尽可能把问题推到最后,随着代码的增多,升级成本其实很有可能也在积累。

原书第10.2节:技术债的度量

程序的圈复杂度主要与分支语句(if、else、switch等)的个数成正相关,所以很多工具都是简单地统计函数中if、while、do、for、?:、catch、switch、case语句和&&、||的操作符的数目来计算得到的。当一段代码汇总含有加多的分支语句,其逻辑复杂度就会增加,这也跟软件开发人员的经验相符。想象如果要你在一段有密密麻麻几十个if/else代码上尝试定位、修复一个缺陷,或是硬生生添加一个功能,如果是在没有单元测试保护的情况下,那会是什么样一个心惊肉跳、如履薄冰的感觉。话又说回来,如果真有这样一段代码,想在上面加测试覆盖所有关键路径也绝对不是一件轻松的差事。

历史数据显示,这样计算出来的复杂度,跟模块中存在的缺陷数,以及为了发现并修正它所需时间,存在相当程度的正相关的关系。复杂度大意味着程序代码可能难于测试和维护。在大型复杂的遗留系统上工作时,圈复杂度显得特别有价值。开发团队通过监视复杂度状态和趋势控制系统中的风险,在出现难以解决的问题之前,及时干预和处理。业界有试验和研究显示,圈复杂度38代码出错的概率达到50%,而圈复杂度在74的代码出错的可能性增加到98%。虽然复杂度的合适区间在不同行业、不同产品会有不同,不过研究指出,大多数情况下,把圈复杂度限制在10左右的位置会是一个不错的选择。业界常用的判断标准是1~4是优秀,5~7是合格,8~10看情况重构,11个以上一定要马上重构。

……

业界发现测试驱动的开发(Test-Driven Development)和低复杂度有着紧密关联。测试驱动出来的代码可以有效减少无效路径,而且如果难以用测试驱动出代码,通常意味着代码的复杂度已经达到一个成都,可能需要重构。

原书第11.1.1节:用户满意度

不过对于接受调查者来讲,问卷是个颇不受欢迎的方式。一方面费时较多,而且由于这种调查缺乏对被调查者的反馈,他们不认为问卷的结果会跟自己有什么关系,也不认为填不填会对自己产生什么影响,会有什么直接价值,因此一般回应的比例很低,填写的人大多数也都是草草了事。有个来自Bain&Company的聪明顾问发明了一种只有一个问题的调查问卷:“你是否愿意向他人推荐这项产品或服务(1-10分)”。这个问题能相当有效地度量个体或服务的直接感受,不过大多数受访者连一个问题的问卷都没兴趣回答,而且这样的调查无法揭示分数高低的原因,因此经常不足以推动任何决策。

原书第11.2.1节:缺陷防范

防范缺陷的主要手段是根据故障的来源来采取行动,降低故障引入的概率。根据来源,常见的可能防范的缺陷主要来自3个方面,如下所述:

  1. 由于技术或是业务能力不足而引入的缺陷,通过学习、能力提升来防范。
  2. 不必要的复杂度提高了引入问题的可能性,降低复杂度,就可以减少人们犯错的机会。比如在可能的情况下用高级编程语言代替较复杂的编程语言,使用成熟的平台、组件,而不是试图自己完成所有的东西。
  3. 在沟通中,信息的丢失或是误解也是造成问题的主要原因。

原书第12.3.3节:鼓励协作和团队学习

如果学习仅仅凭个人的兴趣,对组织目标的帮助也是有限的。个人提升和组织目标的匹配需要协作和团队学习的氛围。下面一些条件对形成这样的氛围会有所帮助。

  • 团队中有共享的目标。这个目标可以是项目的交付成功,可以是产品在某方面超越竞争对手,可以创造有差异化的特性。这个目标应该至少是要略微超越个人的舒适区和团队当前的能力,像我们常说的“要蹦一蹦,才能摸得到”。
  • 个人的学习活动和成果对其他团队成员要有价值,对团队目标要有贡献。学习不仅仅是兴趣,同时也是对团队的责任,责任和承诺是在成员之间形成学习效果正反馈的基础
  • 团队成员之间要充分地讨论和交流学习当中遇到的问题。
  • 学习的过程也是一个反馈的过程,团队成员之间应该及时就方式、投入、目标、问题等,提供直接、建设性的反馈和意见。
  • 团队成员之间就学习的进展和价值表达赞赏和感谢。

图12-6是我的一位同事徐昊所做的一个成功尝试——学习雷达图。他在帮助一个研发团队向学习型组织转型的过程中,让每个人在自己希望提升的领域,列出展现提升能力的行为,并在一个时间轴上把这些行为贴出来。这些领域应该是跟团队的目标有关,对团队成功有价值的。虽然每个人都可以各自拥有一个自己的图,不过推荐的做法是团队共用一个图,并放在大家都看得见的地方。这样,不管团队成员是否做出了响应计划的行为,都会得到团队的反馈,同时不仅可以发现团队的共同兴趣,也可以发现大家以前没注意到的共同忽略的方向。

原书第13章:验证导入(准备篇)

当一个组织引入一套新的方法,期望流程、行为出现改变的时候,通常有两种方法可以促使相关人员产生行动的动机。

其一是发现要解决的问题,也就是我们常常听到顾问们和销售们强调的痛点。他们有个经典问题——“有什么事情让您晚上睡不着啊?”然后把相应的解决方案卖给需要采取行动的人们。这种强调副作用的方法有其心理学的原因。研究证明,人类倾向于把注意力放在负面的事物上,对负面刺激的感触要远远强于正面刺激。这也是为什么悲剧会催人落泪,而喜剧通常不过只让人一笑了之;恼人事会让人彻夜难眠,而高兴事则轻易被忘却。但当人们处于一个比较糟糕的环境时(这也经常是需要变革发生的时候),专注于问题会使我们看到到处都是问题。一方面,改变似乎遥不可及,根本不在控制之中,另一方面也可能让人对问题习以为常——“到处是问题其实就没什么大问题,日子总也能过”,这两方面的因素会很大程度上打消人们行动的念头。有些开发部门的负责人总是一边感慨着“问题太多”,一遍把问题归咎于业务部门、组织机制和环境等等宏观因素,对推动改善的行动无从下手,一味指望自上而下的英明干预。

第二种方式则不是专注于发现和解决问题,而是通过尝试和观察,发现并复制那些证明有效的亮点,这样更容易促进行为的改变,促成变革的发生和持续。所谓榜样的力量是无穷的,成功的尝试能够增加组织的信息,而组织内部的竞争和相互比较也常常会使得成功的局部尝试变成星火燎原的催化剂。因此在组织范围内大规模推行某个方法前,一个验证引入阶段就格外重要,这也就是我们常说的试点。这个阶段的主要目的是寻找“什么在这个组织环境中是工作的”,以此作为后续复制、推广的基础。

原书第14章:验证导入(执行篇)

度量的作用是引导开发组织根据自身的目标,做到“大处着眼,小处入手,失败趁早,学习赶快”(“Think big, act small, fail fast; learn rapidly”)。对于确定的改进方向,我们需要识别合适的细分目标、并通过数据的反馈,尽快验证。

原书第14.3节:指标选择

前面提到,指标的选取需要在有效性、可靠性和成本之间权衡。如果度量体系的设计、实施和运营是由一个独立的团队完成的话(比如在很多实施CMMi的组织里,都有这样一个QA部门),操作中总是不由自主地出现对指标可靠性的倾向。由于这个团队不属于具体开发团队,他们更倾向于使用最客观的度量单位和手段,尽量避免人员主观判断带来的争议,尽量减少对团队和产品上下文的依赖,比如,代码行、覆盖率、圈复杂度等,自动统计得出的数据相对更容易受到青睐。然而,准确的数字和度量有效性之间经常不是那么密切相关,缺乏上下文的度量数据很难直接作为真实目标的决策依据。我们当然会尝试在投入产出合适的情况下提高数据的精确性,不过我们认为,有意义的数据胜过精确的数据

原书第14.4节:数据的收集

内部质量

团队评估后,决定在持续集成服务里集成CheckStyle来检测圈复杂度,用FindBugs来检测代码潜在缺陷数。

外部质量

团队对遗留缺陷的管理主要使用Jira。在迭代开发过程中,如果是验收过程中发现了问题,一般不会录入到系统里,用户故事要被放回待开发状态,必须马上修复,否则故事就不算完成。被记录下来的缺陷通常有几类:

  • 用户故事验收通过之后发现的问题;
  • 来不及修复的级别为一般和轻微的问题。

原书第14.5节:数据的使用

构建时间已经持续维持在20分钟以上,需要考虑:

  1. 通过优化手段,比如重构和精简用例,缩短构建时间;
  2. 通过分级构建,把耗时的验证活动或用例放到晚上,精简实时构建,只包含重要和快速的保障活动
  3. 增加硬件资源,使用分布式构建。

原书第15章:实施推广

如果我们总是在等待别人或者笔的时机,变革将永远不会到来。我们就是自己一直在等待的人。我们所追求的改变就是我们自己。” ——巴拉克·奥巴马

原书第15.6.3节:目标团队

兴趣和认知必须要能够转化为投入和行动。我们不能假设大家知道了原理就有动力移出舒适区,更何况和诺团队都对度量体系这种可能干扰开发的活动有本能的抵触情绪。

首先,客户不会为企业部署了度量体系而买单。度量本身不会直接影响最终产品的功能和使用,也就是说,并不为可工作的软件直接创造价值,因而好像是个应该减少,甚至消除的活动。不错,如果度量不能为帮助我们更好地完成直接创造价值的活动,那么就是浪费。我们在引入任何新的度量之前,都应该认真评估其带来的价值。

度量引导的方向未必是团队认可的方向。有些目标,像是更高的单元测试覆盖率,或是把一个特性的端到端测试完成才算完成,这样的目标增加了开发人员设计和编码之外的责任,而很多开发人员并不认为这些工作是他们的责任。然而,Mary Poppendieck认为责任(做什么)、知识(怎么做)、行动(完成工作)、反馈(从结果中学习),这些活动的割裂是造成移交这种浪费产生的原因。如果一个一体化团队共同承担着端到端的交付责任以及相关工作,那么诸如所谓代码之外不是我的责任,这样的问题就不应该存在。

抵触的另一个原因是,对于有些度量,团队其实并不知道是干啥用的,是给谁用的,因此只看到了负担,而不清楚价值,度量被归类到某些无聊官僚的没事找事。这里关键是缺乏反馈。当有些数据是给管理层使用,或是给其他像计划部门、过程改进部门这样的功能部门使用,他们的使用结果并没有有效的路径感喟到数据的源头,团队不知道这些数据对什么决策产生了什么作用,引发了什么后续行动。

还有的情况是度量发现了问题,但或者由于进度的压力,又或者由于管理层的忽视,这些问题摆在那里,久而久之大家都习惯了。对于度量暴露的问题没有行动,或是行动没有结果,度量体系就成了摆设,大家也就没有兴趣关注了。

最后还有一种更糟糕的情况,度量成了奖惩的主要依据,利害相关,大家要么心怀顾忌,要么抱着你好、我好、大家好的“共赢”态度,跟度量体系捉迷藏

赞(3) 打赏
转载需注明来源并给出来源页链接:峰间的云 » 《精益软件度量》摘记

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏