上周写的一次代码评审引发的TDD发布到TDD讨论群后(感兴趣的同学可以私信爱睡觉加入,微信号Vic-VVu),群里的大神们纷纷给了反馈,印象最深的来自麦宇安大神:
@葛亮 测试没有清晰表达意图,怎么就best fit了,那些1 2之类的魔法数字代表什么?光看测试完全不知道在测什么!
听上去虽然有些逆耳,但是逆耳的一般是忠言,苦口的一般是良药,赶紧再回去看看自己的测试代码,如果没有上下文,站在第一次读代码的读者角度,的确完全不知道测试的是什么,自以为深谙Clean Code之道的我顿时倍感惭愧。。。
@Test
public void two_matched_tariffs_with_different_rank() {
Tariff matchedTariff1 = new Tariff(1, 1);
Tariff matchedTariff2 = new Tariff(2, 2);
List<Tariff> matchedTariffs = Arrays.asList(matchedTariff1, matchedTariff2);
List<Tariff> bestFitTariffs = Arrays.asList(matchedTariff1);
assertListEqual(bestFitTariffs, selectBestFit(matchedTariffs));
}
知错能改,善莫大焉,于是立马重构,首先消除魔法数字,代码如下,
@Test
public void two_matched_tariffs_with_different_rank() {
Tariff matchedTariff1 = new Tariff(GEO_LEVEL.TOWN, GEO_LEVEL.TOWN);
Tariff matchedTariff2 = new Tariff(GEO_LEVEL.CITY, GEO_LEVEL.CITY);
List<Tariff> matchedTariffs = Arrays.asList(matchedTariff1, matchedTariff2);
List<Tariff> bestFitTariffs = Arrays.asList(matchedTariff1);
assertListEqual(bestFitTariffs, selectBestFit(matchedTariffs));
}
测试通过,代码稍微好一些了,但是测试意图还不够明显,决定重命名一下测试方法和几个关键变量,代码如下,
@Test
public void town2town_is_more_fit_than_city2city_tariff() {
Tariff town2town = new Tariff(GEO_LEVEL.TOWN, GEO_LEVEL.TOWN);
Tariff city2city = new Tariff(GEO_LEVEL.CITY, GEO_LEVEL.CITY);
List<Tariff> candidateTariffs = Arrays.asList(town2town, city2city);
List<Tariff> bestFitTariffs = Arrays.asList(town2town);
assertListEqual(bestFitTariffs, selectBestFit(candidateTariffs));
}
测试通过,比较下现在的代码和最初的代码,感觉好多了:)
群里面的另外一名大神还提到性能问题,说二叉树实现的性能会比现在的简单实现好,这让我想到下面这句名言,
“在编程中,过早优化是万恶之源。 ” —— Donald Ervin Knuth,1974
Donald是经典巨著《计算机程序设计的艺术》的作者,荣获1974年的图灵奖。在代码可读性和性能之间我会优秀选择代码可读性,因为你做的局部性能优化可能在系统级别微不足道,以本文提到的代码为例,我特意测试了输入10000和100000个Tariff时二叉树实现和简单实现的性能差异,
数据量 | 二叉树实现 | 简单实现 |
---|---|---|
10,000 | 16ms | 21ms |
100,000 | 198ms | 390ms |
可以看出二叉树的性能的确比简单实现的性能好一些,但是现实业务中,匹配的报价条目最多不会超过100条,性能基本上不会有差异,所以这时候我们更应该优先选择代码可读性。
有一种代码叫做别人写的代码,相信每个程序员都有过读这种代码的痛苦经历,为了减少这种经历,难道我们不应该多花一些时间和精力在方法,变量的命名上吗,难道我们不应该多花点时间和精力让代码读起来更简单一些吗?
今天借Code Review例会的机会,把这些想法和二叉树实现的作者分享了一下并解答了一些问题,令人开心的是最终大家愉快地达成了一致:)