成功的软件产品需要的技能(by Ron Jeffries)

2019-04-14

译者前言:

这是Ron Jeffries最近写的一篇博客。Ron Jeffries是敏捷开发的先驱、“极限编程”的三位提出人之一。他写的书除了关于“极限编程”的以外,还有2015年出版的《The Nature of Software》(软件的性质)。

这篇博客是对作者之前的发表的23条Twitter内容的补充,原文标题只是《Technical Skills》,我根据那些推文的内容加上了“成功的软件产品”的定语。原文链接:Technical Kills

以下译文中的“我”均为Ron Jeffries。

第一条推文 (23条推文中的第一条。)

原文前言

一些读者在我的“推文风暴”后要求罗列出所指的所有必要的技能。我做不到,但我可以写下这篇博客介绍下其中的一些。

一些相关文章:

敏捷方法的要求

上面列出的“(Imposing Article)推行敏捷”一文在描述敏捷软件开发组织所需要的能力方面做了很好的工作。换用一种略有不同的表述方法的话,要想做好敏捷软件开发,我们需要至少达到这些貌似简单,实则并不容易的事情。按照开发一个产品的顺序:

  • 在产品开发的第一个星期,制作一个可以运行的、经过测试的、产品的可用版本(Increment: 增量)。这个版本的功能无疑是非常少的,但需要包含产品中最本质的一些东西。
  • 这之后的每个星期,更新这个版本以包含任何选定的要开发的功能。这些功能是“客户可见”的,并且是经过团队的“专注业务”的计划流程选出来的。(这可能是Scrum中的“Product Owner(业主)”、真正的用户、跨团队的流程,或其它什么名字。它总是专注于提供给用户的能力,而不是架构或者设计一类的东西。)
  • 所有的增量(版本)都必须是经过充分测试过的。我说的“充分测试”是指我们几乎能确定知道其中包含有多少缺陷,并且我们保持这个数字接近0。当这个数字超过0时,我们修复缺陷,同时修复我们的流程中任何导致引入这些缺陷的部分。
  • 增量的代码总是“干净”的。名字是清晰且一致的。代码中只包含非常少的重复或“复制-粘贴”的代码。代码由高内聚、低耦合的模块(对象、函数……)组成。当代码偏离“干净”的标准——这总是会发生的——就把它推回正途。
  • 每个递增版本的设计和架构总是在我们能力范围内尽可能好。当它们偏离了我们目前的需要,我们也会及时修正它们。

以上这些听上去似乎令人畏惧:我希望如此。但这也几乎是实施最简单的敏捷方法——Scrum——所要求的。不信?读一下非常简短的Scrum指南,再想一想增量式交付真正的含义。

这意味着每一个星期(如果你是软蛋的话也可以是两周)都要交付一个真正的、测试过的、能工作的、生长中的产品版本,这个版本是可以发布的,拥有非常高的质量标准。既然你必须每个星期(或两个)都这样做,它必须是从内到外都是非常好的。

需要的技能

上述列表非常简单,基本上来说我们需要在第一个星期构建一个接近完美的产品的迷你版本,并且在一周复一周增加越来越多的功能的过程中,在任何方面都保持高质量。

这说起来很简单,但要做到并不容易。需要很多技能才能做到这点,并且其中的很大部分在学校里不教,你也没法通过阅读《180天学会Python》来得到这些技能。它们不在这一类的书里。

我们要怎么做才能达成上述列表中的目标?让我们一起来想。

  • 细分故事:为了在一个星期中获得一个可用的版本,我们需要从产品的功能中切分出非常小的一部分,小到我们可以在一个星期中完成。
  • 测试所有新的:因为缺陷数必须总是达到或趋近于0,因此每个新增加的部分在开发的同时要经过完整的测试——在同一周。
  • 测试所有旧的:但是因为我们改进设计、消除重复、使所有功能各归其位,我们每个星期都需要测试所有以前实现的特性,而不仅仅是新的。
  • 进化代码、设计和架构:我们也许可以、也许不能在第一周就在脑子里构思出所有的设计和架构。我猜不能。但我们必须总是有好的代码、设计和架构,这意味着在扩展产品功能的同时不断改进实际的代码、设计和架构。

这些综合起来意味着很多技能。程序员并非一开始就知道如何做到这些。我认识的很多支持敏捷方法的技术人员多年来一直在学习将这些事越做越好。这些事貌似简单,实际并不容易。

技术实践

有很多方法和工具帮助我们完成这些简单但不容易做好的事情。目前我所了解的,其中最好的有:

  • 测试驱动开发:TDD是这样一种实践方法:我们写程序时先为我们将要开发的一小部分功能写一小段测试,并且确保这个测试不会通过。然后我们写一小段程序,使这个测试、以及其它所有测试都能通过。接下来我们马上改进代码质量,并且同样确保所有的测试能通过。因为我们每几分钟就要运行一次所有的测试,因此测试必须自动化,并且执行起来很快。
  • 重构:上述改进代码质量的方法称为“重构”,它指的是通过少量的修改——而不是重写和替换大量的代码——将代码逐步推回正轨。如果每一个功能的增加都是非常微小的,对设计的影响也总是非常小的,那么重构将会非常直接。当然有时候,也会困难一些。
  • 验收测试驱动开发(ATDD):对我而言ATDD主要是一种在业务侧的利益相关人和技术侧进行沟通的技术。它在产品中提供一层额外的信心保障,但对我而言,(它在)沟通方面的意义更加重要。ATDD是一种外层测试,在TDD的外面。我们构建的是专注于客户的功能,我们使用“验收测试”、“客户测试”或者“产品测试”来描述我们的计划,然后向我们自己、以及所有利益相关方展示系统确实达到了我们计划中的目标。既然产品和设计是在不断发展的,我们需要随时能检查所有的系统特性,所以这些测试如同TDD中的测试一样也需要是自动化的。
  • 关于架构和设计的丰富知识:这不完全是一种技术或工具,但这很关键,所以我增加了这一条1。我们提到了重构,这是我们在递进地开发产品的过程中保持设计和架构不断进化的手段。要做到这一点,我们需要了解好的架构和设计与不怎么好的架构和设计之间的差别。在我们的工具箱中需要有丰富的不同架构与设计的选项,从非常简单的到非常复杂的架构和设计,在系统不断成长的过程中,我们会需要后者。一个人对架构、代码与设计的质量的了解永远也不会嫌多。当然,我们也需要平滑地、递进地、一点一点地运用这些知识。
  • 持续集成:我们发现,一般来说,为了每周都有一个经过测试的可用产品版本,我们确实需要一个随时可用的、经过测试的产品,每天、甚至每个几个小时这个版本就增长一些。有一整套的工具和技术来支持持续集成。

还有很多……

以上只是我们需要掌握的一些主要技术的统称。你可以找到一些书籍和网络文章来学习。你也可以找到在线课程、或者通过内部培训来学习。

在这个简短的列表背后,是对终身学习的需求。既然好的敏捷软件开发要求随时都有可工作的软件,那么其中某些技术绝对是做好敏捷开发所必须的。


  1. 感谢James Shore提醒我被遗漏的这一点。还有更多的吗?请告诉我。当然,有无穷的事物我们需要了解:这是我最喜欢的。关于James和Diana Larsen, 请看Agile Fluency effort 



blog comments powered by Disqus