技术开发 频道

“XP 精华”重访,第2部分

【IT168 技术文章】

    在揭开极端编程的神秘面纱系列的这个月的文章中,Roy Miller 解释了作为 XP 团队的一个程序员意味着什么,以及六种程序员方法如何适合特定的环境。虽然 19 种 XP 方法都很重要,但对于一个开发软件的团队来说,程序员方法是最重要的。
    程序员方法:创建系统
    XP 程序员方法描述了程序员在创建团队所需的系统时需要做什么事情。对于许多人来说,这些方法就是 XP。当然,XP 不仅仅是关于编写代码的,但如果没有代码,整个过程就是在浪费时间。就象上个月一样,这些方法中的有一些并不在最初的 12 种 XP 方法之列。在每个名称后,我都会插入说明,指出那种方法是新的、未改动的,还是映射到初始名称的。注意,这些名称是不断变化的,但原则应该不会变。(您可能已经注意到,最初的一个程序员方法,即编码标准(Coding Standard),已经不在列表中了。原因是这个方法在新的列表中将是多余的。编码标准将在程序员编写代码时出现。您没必要将它作为一种单独的方法。)

    在我们讨论程序员方法之前,我们先来弄清楚上个月的一些问题。我将在这个专栏中讨论的修改过的/重命名的/新的方法是我经过对 Kent Beck 写的两篇尚未发表的文章进行深思熟虑后的结果。据我所知,XP 目前还没有经过任何官方更改,这些方法和思想还没有以任何正式的方式出现在领导组或类似的位置上。可能不会有任何官方的更改。当然也没有任何种类的对这些方法进行正式修订的工作。我想此刻我最想说的是我所写的可能会成为将来某个时候的 XP。可能看起来会有点不同。我希望我的想法会对这些讨论有所帮助。阅读时风险自负。

    测试优先的开发(映射到测试(testing))
    无论程序员什么时候修改了代码,他们都需要知道自己刚才所做的是改善了代码还是破坏了一些东西。更重要的是,他们要维持必要的纪律,从而只需创建最少数量的代码就能够完成所需的工作,而不是创建规模庞大的代码,里面包含一大堆可能后来有人会需要的东西。这就是测试优先的开发的主旨所在。

    在 XP 中有两种测试:单元测试和验收测试。这些是典型的名称,但我不喜欢。对于我来说,这两个名字太莫名其妙了。我更喜欢 Ron Jeffries 在他写的“What is Extreme Programming?”(请参阅参考资料)中建议的名字:客户测试和程序员测试。

    这两个名称一语中的地道出了施行这两类测试的原因。程序员在编写代码的同时编写程序员测试。客户在定义了素材(stories)后编写客户测试。程序员测试告诉开发人员系统是不是在任何时刻都能正常运行(象客户定义的那样)。客户测试告诉团队系统是否执行用户希望它做的工作。在这里我将讨论程序员测试,并将在下个月讨论客户测试。

    假设团队使用的是一种面向对象的语言,如 Java 语言,开发者在为每个有可能崩溃的方法编码之前为其编写程序员测试(大多数时候,只是为公共接口编写程序员测试)。然后他们只需编写足够的代码使其能通过测试。有时人们会发现这有点奇怪,但答案很简单。编写测试首先可以为您提供:

    一组可能最完整的测试,它可以增加您对代码的信心
    可能能工作的最简单的代码,这使得后来重构代码更为简单。
    更清楚的代码意图,使得后来的理解和重构更加容易。
    开发人员只有在通过所有程序员测试后才可以将代码检入到源代码资源库中。程序员测试使开发人员有信心相信他们的代码能够工作。他们留下了线索,使其他开发者能够理解最初的开发者的意图(我很少看到过比这更好的代码文档)。程序员测试还给予开发者重构代码的勇气,因为测试失败会立即告诉开发者是不是有地方出了问题。程序员测试应该实现自动化,并且要给出清楚的通过或失败结果。xUnit 框架(请参阅参考资料)做到的远不止这些,因此,我所知道的大多数 XP 团队都使用它们。几乎您能想到的每种语言都有自己的 xUnit。只需用您选择的语言或工具代替“x”即可(例如,Microsoft Visual Basic 的 VBUnit、C++ 的 CppUnit 等等)。

    作为一名程序员,我常常对使用程序员测试进行编码与不使用程序员测试进行编码之间的差别感到吃惊。我发现自己在编写代码时会执行一些非常小的步骤。实际上,在我执行一些小到一定程度的步骤时,我不必进行太多的调试工作,因为问题的根源会变得很明显:它就出在我正在编写的那行代码上。对我来说,比较明显的就是首先编写测试经常会推动我尽可能去创建最简单的代码。

    我确信您已经编写了您认为以后会需要的代码,但您真的需要它们吗?可能会需要,但如果不需要的话,您会除去它们吗?或许不会。所以,它们只是放在那里,而没什么用处。如果您的测试确切地告诉您要写多少代码会怎样?如果您只编写足够通过测试的代码,而不写多余的代码会怎样?可能您拥有的代码会更少,并且它们都会被派上用场。这就是我想编写的那种代码。当您编写自己的测试代码时,测试会推动(drive)代码。结果,当测试推动代码时,您的代码就会大有改观。根据我的经验,在测试推动代码时,我的代码就会简单得多,而且我一直在设法使它们更为简单。Kent Beck 正在写一本名为 Test-Driven Development 的书(请参阅参考资料),这本书详细讲解了这种方法。我向您推荐它。实际上,我更倾向于把这种方法命名为测试推动的开发(Test-Driven Development)。

    结对编程(未改动)
    在 XP 中,所有的生产代码都是由结对的开发者编写的。大多数开发者都从不曾有过与另一个人一起实际编写代码的经历,刚开始会感到有点不习惯。结对编程通常意味着两名开发者共享一台计算机。一个人键入代码(“司机”(driver)),另一个人帮他指路(“领航员”(navigator)或称“伙伴”(partner))。如果司机被困住了(或失败了),或者如果领航员有一个好主意但不通过键盘输入就不能很好地描述,那么当前的司机可以放弃控制权,做一会儿领航员。每个人都应该经常切换角色。一旦您习惯了这些角色,来回切换就会相当轻松。

    这种方法听起来好象效率不高。我一直很喜欢 Martin Fowler 的回答:“当人们说结对编程会降低工作效率时,我回答说,'如果编程最耗时间的部分是打字,那么这是对的。'”实际上,结对编程或者简称“结对”,可以提供许多好处,包括:

    所有的设计决定都用了至少两个人的智慧。
    至少有两个人熟悉系统的每一部分。
    两个人都忽略测试或其它任务的可能性更小。
    改变各对的组合可以在团队范围内传播知识
    代码通常至少被一个人复查。
    实验法研究指出代码复查可以提高代码的质量,但是我讨厌那样做。我还认为要正确地进行复查将非常困难,复查工作没有结对编程那么有效。如果每行生产代码都被一个对代码的意图非常熟悉的人复查过会怎样?结对编程为您提供的刚好就是这一点。只有真正参与才能足够忠实。

    Alistair Cockburn 与 Laurie Williams 合写的 The Costs and Benefits of Pair Programming(请参阅参考资料)中讨论的研究也表明结对编程实际上要比单独编程效率高。这与我们的直觉有点不一样。大多数管理人员(我曾经是其中之一)将看到两个开发者做一个开发者的工作,然后就看不出更多的东西了。这不是理性的思维方式。这种想法过于简单。这也是错误的。

0
相关文章