广斌,你好
现在才回复似乎有点太晚了。主要是因为这几道题以前都没有练习过,所以没好意思发言。
其实相对于kata题目,我倒是更想从你这里学习学习组织代码道场的经验。其实从去年我就有想法要在同事间发起道场活动。不过大半年过去了,还停留在想法阶段。看来今年一定要实现这个目标了。不知道你组织这么久,有没有什么经验建议可以分享啊? :)
前一段恰好做了哈利波特这道题,以前一直觉得题目说明太长就没尝试过。做下来发现这道题还挺有意思的。
这是我的练习记录:
实话说我头一次看你的代码的时候没看懂,咱们俩的思路差异蛮大的 :)
后来顺着提交历史看了一遍总算搞明白了,用一个数组来统计每种数量书的分布是个挺新颖的思路。另外这是我第一次看到中文方法和测试名,第一眼看的时候着实懵了一下。
看完以后的几点想法:
1,似乎在“重构代码”那一步跳跃比较大。
前面一步书的的数量恰好为5,4,3,2的时候用统计数组从小到大判断非常的直观。然后这一步重构的时候,其实已经改变了代码行为。完全完成后才补上了2+1,2+2,以及5+3或4+4的逻辑。如果不是因为漏提交的话,看起来似乎这一步较大的重构时,是按照脑子里想到的测试用例在增加功能,而没有通过实际的测试进行驱动。
2,我注意到在这步较大的重构前,增加了一句println语句。
我感觉这是一种代码味道,表现出目前的测试无法为开发提供足够的反馈。
有时候的确因为某个失误可能程序的行为完全摸不到头脑,这时退回上一步重来,打印log,或者单步跟踪都是可行的。不过这些手段只是用来搞清程序行为的临时方法,不应该存在超过一次绿灯。一旦迷惑搞清楚了,下一次测试中应该改进测试用例来更明确的体现程序行为。
我猜测这句println的目的是更清楚的看到统计数组的情况,这样才能总结出满足不同用例的判断条件。
这样的话,一个选择是把统计数组暴露给测试,在测试里明确说明数组和不同使用场景的关联关系。
如果觉得这样太丑的话,可以把数组分离到另一个类中,这样numOfThreeAndFiveBooks,existThreeAndFiveBooks等都可以作为公有方法暴露出来。原本需要println来观察的行为也可以写到这个类的测试中去了。
3,是选择五本书加三本书的折扣,还是选择两套四本书的折扣?
从用户的需求而言,只是要选择价格最低的。而两套四本书的方案,是由于折扣率设置产生的一个结果,它本身并不是需求。把它写入代码逻辑似乎产生了不必要耦合,而且模糊了真正的业务逻辑。
4,caculate方法中的switch语句非常适合用数组或map重构。
把discount1,2,3,4,5放入discounts数组中,cauculate方法只需要一句代码即可:
return i * sigelPrice * discounts[i-1] * num