• 2007-07-04

    消除浪费的敏捷

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://dreamhead.blogbus.com/logs/6381752.html

    敏捷的核心:消除浪费,走向精益

    谈到敏捷,你会想起什么呢?测试驱动开发?结对编程?我刚到ThoughtWorks不久,gigix就和我提到过,关于敏捷消除浪费的观点,说实话,我一直不太理解这个观点。不过,随着在ThoughtWorks体会的点滴逐渐增多,我慢慢的体会到这句话的含义。

    举个简单的例子,为什么要做测试驱动开发呢?从字面上看,将“测试”放在前面,提高了测试的重要性,告诉人们应该注意这一重要但经常被忽略的事实,这一点对于保证软件质量来说,确实是应该的,再有单元测试的存在让自动化回归测试变得容易了许多,还有写测试的价值会让人从不同的角度考虑设计,也许会让设计的耦合性大大降低。人们通常想不通的一点是,为什么要先写测试。如果只是单纯的交换编码和测试的位置,实际上并不会带来太多的好处。那该从怎样的角度理解测试驱动开发呢?测试代表着什么呢?需求。软件开发的目的就是为了满足需求,如果能够把需求确定了,编写代码满足它就相对容易多了。从需求出发,按照需求编写满足需求的最简单代码,而不去做许多额外的工作,这就是测试驱动开发不同于传统编写方式的地方。按照传统的方式先写代码,后写测试的话,我们的测试代码需要做的工作尽可能覆盖代码的路径,而为了覆盖面尽可能大,我们就需要花费许多额外的努力,这就是浪费。

    敏捷的思想不仅仅体现在测试上,在这两个月左右的时间里,我对设计的理解也开始发生了一些转变。曾经我对设计的理解是设计一个能够应对未来变化的美好结构,但事实上,这种竭尽全力设计出来的“好”设计总是轻而易举的被现实问题打败。为什么呢?因为这个设计是想出来的,并不是基于实际的需求逐步演化出来的。在ThoughtWorks的招聘流程中,会有一个编写程序的过程。在这个过程中,我们总会听到应聘者说他的设计是为了应对将来的变化。但事实上,这样的变化是否存在呢?不一定,多半是没有的。所以,许多看起来比较华丽的设计完全经不起推敲。其中的一个例子是,为了面向接口编程,设计一个接口,却只有一个对应的实现类,本应枝繁叶茂的继承树显得十分单薄。当然,这里并不是说面向接口编程就不好,但当只有一种情况时,就做这种抽象显然是一种过度设计,过度设计就意味着浪费,在这个例子里面,至少需要多付出编写一个接口的代价。也许你会说,未来如果真的出现第二种或者更多的情况,那该怎么办。很简单,等真正出现了再做也来得及。

    当然,问题并不绝对。一个例子是在数据库的设计通常我们会提前做出。基于前面的讨论,也许有人会认为这么做不太敏捷,恰恰相反,因为随着项目的进行,数据库修改的成本会越来越大,所以,我们宁肯在项目的前期多做些功课,以保证后面尽可能不去或少去修改它,以便减少浪费,所以,这种选择也是敏捷指导下的选择。

    也许,这种讨论会给人一种人嘴两张皮的印象,其实,这和做许多事一样,就是一个度的把握。所以,很多人都看了一些敏捷的书,但用到实际中,却总觉得不是那么回事。

    如果开头的那篇文章是写给各种各样的管理者的,那我这篇算是写给程序员的吧!


    历史上的今天:





    引用地址:

    评论

  • 曾经,每个类都有个接口,我也认为没必要,可后来联系到测试,才觉得大部分类还是有接口比较好,虽然真正的实现类只有一个,但测试要用到的mock类呢?
    dreamhead回复Samuel Cai说:
    测试驱动开发时,你会从测试入手,类是逐渐演化出的,如果需要,不是完全不可以做的。但预先设计出来的,多半是有问题的。

    再有,如果一个接口只有一个实现类,直接使用这个类就好了。
    2007-07-04 22:08:15