TDD这几年在公司被谈的比较多。早期接触的时候,觉得不过如此麽,先写用例后写用例有什么区别?所以大多数时候,都是披着“TDD”的外衣,该怎么开发还是怎么开发,提交代码的时候把用例补上不就结了!
其实说TDD很容易的,我想不是大牛,就是小白了(至少对TDD是小白,即使严格奉行先写用例后编码)。
现在我对TDD的理解,认为难点不在于形式上是先写用例还是先写代码,而是在于指导甚至决定如何编码!对于简单的需求,特别是一些设计好的用于训练TDD的题目(特点是需求会一步步给出,难度递增),使得TDD实践既轻松又理所当然。而实际的产品需求往往都很复杂,如果没有架构师、系统设计师的层层分解,上来就说可以用TDD和重构来解决问题,那绝对是大牛!
那到底用TDD+重构能不能解决问题呢?当然能!都说了那是大牛!但是这些人牛在哪里呢?我能想到的有几点:
- 能快速找到问题的切入点,由浅入深分析出问题的脉络:TDD实践的题目为什么做起来那么顺?就是因为复杂问题已经被理顺了,让实践者很容易操作。而大牛可以在较短的时间内,知道第一个用例应该怎么设计,才能把面对问题已经蒙圈的开发者的注意力拉回来,能着手开始编码;接着用一系列的用例,引导开发工作。大牛的这些用例设计,已经体现他们对复杂问题的抽象、简化、分解。
能从需求中抽象出接口:第一个用例本身校验什么数据已经不是最重要(第一个用例往往是很简单的),用例用到的接口才最重要!业务代码必须依据这个接口开始设计,来满足用例,使其通过。而随着用例复杂度的增加,业务代码的复杂度也随之增加,代码的设计也就自然而然的融入其中。
这里其实有个争论点:应该自顶向下设计,还是自底向上设计?其实我个人并不太认可在编程实践中有完全的自底向上设计。面对现实问题,若不从整体上做个初步设计,并对可行性稍加验证(可能仅仅是推理验证,不见得要有原型系统),很难想象完全的自底向上设计有可能会经历多么大的重构甚至重写。
当然还有论点,说即使做了系统设计,仍然局限于个人对问题认知的深度,也很容易出现大规模的重构甚至重写。所以提倡简单设计!就我个人的经历而言,这真是一个极易误导人的论调。什么是简单设计?标准是什么?大牛和小白的简单设计的差距是什么?就像敏捷提倡工作的软件 高于 详尽的文档一样,最后往往变成了敏捷不需要文档。我觉得,不靠谱的简单设计,还不如让稍微靠谱一些的架构师多花点脑细胞。
所以,TDD是个技术活!