最近做了一个算24的练习。
过程很纠结,观看过程中如有不适,我非常抱歉。
结果代码也仅仅是能工作而已,远远谈不上清晰优雅。
之所以拿出来分享,是想说说这次练习我的一些体会。
1. TDD和预先设计的关系。
基本上我的理解是TDD要避免过度设计,但是什么是“过度”却是非常难把握的。
以前我的尝试中,经常因为事先完全没有设计,在TDD过程中发觉走偏了。因为觉得似乎从头再写更简单一点,就中途放弃了。
在这次的过程中,至少有3次我都感到走入歧途了。不过这次硬着头皮写,竟然最终也写出了一个能工作的版本。深深感觉到今年以来做kata是对TDD技术的提高。
当然这样开发是否有效率是另外一个问题了。
2. 有时候要重构要先写烂代码。
以前我总是尽量深思熟虑后再写代码,力求一次写对。因为怕代码写乱以后,就很难再改回来了。虽然做练习的时候第一个Test可能会hard code一个结果来通过,但随着深入进行到代码比较复杂,一处修改牵涉多条逻辑的时候,就越来越不敢简单粗暴的通过测试了。这样往往因为想不清楚就卡在某处无法推进了,这也是前面说有时候觉得走入死胡同放弃的一个原因。
通过这段时间TDD和重构的练习。现在对烂代码有了一定的容忍度。可以捏着鼻子先写一句很傻,而且只在特定情况正确的代码。因为我已经有信心可以从Test中获得足够多的反馈。而且也相信只要写足够多的傻代码,我会在后续的重构中找到比较聪明的写法。
最重要的体会是,很傻、只是部分正确的代码,也比完全没代码要好一点。
3. TDD与所产生的代码设计的关系。
到这个练习告一段落的时候,我感觉明显代码距离理想的结果还很远,估计还需要相当多次的重构。
在这个点上我有种很熟悉的感觉,代码非常像实际工作中碰到的情况:有一定的逻辑,但是又不充分体现业务逻辑。代码中有明显的重复,却没有一眼看得到的方案去整合这些重复。
经过TDD给代码带来了相当数量的测试用例,但是这些测试还没有清晰的描绘出代码块直接的关系,以及代码执行的路径。另外因为测试用例没有清晰表达出所要的覆盖目的,导致代码中至少还埋着一个bug。
我的感觉是,TDD的过程是通过分解逐步深入理解问题的过程,如果最终对问题的理解还不清晰,代码并不会因为做了TDD而变得清晰。
不知道这个题目用 London School 方式来做会不会更容易些。准备下次尝试一下。