在去年举办的敏捷新加坡 大会 的演讲中, Steve Freeman 为听众分析了 TDD 为什么会被人错误地理解、并且在各种实际应用中会经常产生误用的原因。他同时还说明了为什么 SOLID 架构原则依然非常重要的原因,甚至很可能比过去的任何时刻都更加重要。
在会议结束之后,InfoQ有幸与 Freeman 进行了一次访谈,内容包括他的演讲以及背后的相关思想。
InfoQ:你的第一场演讲名为“TDD——这不是我们的意图”,为什么要取这样一个标题?你想要表达的意思是什么?
之所以取了这样一个有些耸人听闻的标题,主要还是为了吸引大家的注意力。这场演讲的本质是“重新回到基本”,我试图让人们回想起测试驱动开发的基本原则,并为听众解释为什么这种方式适合于我。准备这样一场演讲的目的之一,是对这一段时间以来一直被人提起的“TDD是否已死?”这一讨论进行回应,也是对于我在同一主题上的其它几场演讲的重新整理。
InfoQ:这一段时间以来,人们在实现TDD的常见方式中有哪些错误的地方?
在我进行培训和顾问工作的过程中,我看到许多团队似乎都没有抓住要点。他们往往创建了大量的测试代码,但这些代码既不能帮助他们找到bug,也无法对待测试的代码起到任何解释说明的作用。在很多情况下,他们编写测试的原因只是因为有人要求他们这么做,但没有人对这一流程的目的或是实践技巧加以任何说明。当他们终于对这个令人头疼的麻烦感到忍无可忍时,他们要么选择放弃测试,要么转而寻求其它流行的技术。我想表达的是,TDD与其它任何技术一样,只有在使用者理解了它的目的,并且有足够的时间去理解它的情况下才能够发挥作用。如果用一句话来解释,那就是思考这段测试反映出了代码的哪些意图。如果你无法理解这一意图,那么要么是代码、要么是测试本身,总有一个需要进行改进,也很可能两者都需要改进。
InfoQ:你能否指出一些常见的反模式?对于那些还在使用反模式的团队,你有什么样的建议?
多数反模式都会表现出某些复杂性和脆弱性。这方面的一种症状是测试开始变得难以阅读,另一种症状是无法在不产生任何破坏的情况下进行代码改动。解决方案就是真正地去聆听这些测试,并对这些测试的背压进行回应。这或许意味着你需要对测试进行整理,让它能够正确地表现意图,或是将代码分解为较小的单元、或是不要通过对字节代码的操作去做一些貌似聪明的事。
InfoQ:团队怎样才能够做到,让他们的代码和测试成为一种与未来进行对话的基础呢?
我提到过,要让测试阅读起来很通顺,是吧?这一实践的核心就是找到难以编写的新测试,这就是你改善设计的时刻,你需要对当前的结构进行认真思考。这个测试或许能够告诉你某些问题:比如你的代码单元太大、你需要为新的特性暴露出更多的内容、或是其它各种问题。重要的地方在于,暂停你的工作,让测试反映出的问题,或许还要进行重构,而不是一味地追求速度。
InfoQ:你的另一场演讲的内容是“在SOLID基础上创建应用”——这些基础是指什么?
这个标题会让人感到有些不解,其实基础就是指SOLID,这是Michael Feather对于面向对象的几个原则设计的一种首字母缩写方式。我们将在这一基础上创建更复杂的应用程序。
InfoQ:SOLID的思想存在了已经有很长一段时间了,为什么人们还是不能有效地应用这些思想呢?
举办这场演讲的一个目标在于,我在观察中发现,许多系统的各个组件虽然能够运行良好,但整个系统是难以使用的。我们认为,这是因为这些系统对于中间层结构投入的关注还不够多。
InfoQ:为了让程序员能够真正地在某个实用的基础上进行工作,他们能够做些什么,或者说应该做些什么改变吗?
这场演讲的核心在于,在我们进行编码时,应当把可组合性作为第一等的需求进行思考。仅仅对方法进行链接、或是用大量分解后的词语组成一个方法名,并不代表我们能够保持代码的灵活性。真正对我们有帮助的是,认真思考如何设计我们的对象,让我们能够在创建新的行为时方便地将它们进行组合。实现这一点的部分因素在于,在定义行为的代码和传递给该行为的状态之间保持某种清晰的界限。这一点是刚流行起来的函数式编程中所具备的一个优点,而要获得这种组合性所带来的好处,并不是说一定要使用Haskell语言不可。
查看英文原文: Steve Freeman on What's Wrong with Most TDD Implementations and Building on SOLID Foundations