我的反馈如下:
编码操作相关:
+ 用键盘和快捷键来编程不错
- 可以考虑用vi来编程
- 可以考虑设置快捷键来切换测试和代码
TDD相关:
+ 第一个TDD cycle (love all) 做的不错
+ 第二个TDD cycle (fifteen all) 做的不错
+ 第三个TDD cycle (thirty all) 中应该要做重构了, 因为love, fifteen, thirty 与 0, 1, 2的重复还是蛮明显的
+ 第四个TDD cycle (forty all) 整体不错, 重构做的很清晰. 虽然可以考虑步子再小一点(比如数组先只有love, 而不是都加上), 但是我想那时你应该已经把重复代码看得很清楚了
- - translation数组可以考虑是 static final, 并且初始化时可以不写 new String[], 而只写 {“love” …}
- - translation这个变量名可以考虑改成 scoreText 之类的
- - 需求理解错了吧, 3比3时应该是 “deuce” 而不是 “forty all”
- 第五个TDD cycle (fifteen love) 中其他不错, 不过应该要重构代码. “fifteen”和”love”明显和数组中的元素重复, 应该被替换成 translation[1] 和 translation[0]
+ 第六个TDD cycle (thirty love) 做的不错
- - 不过, 我觉得给if加个 {} 没有什么意思, {} 在这里属于多余的代码
+ 第七个TDD cycle (player one win) 做的不错
- 第八个TDD cycle (player one advantage) 让测试通过做的有点快了, 我可能会选择另加一个新的 if (playerOne == 4 && playerTwo == 3) 来实现. 把advantage的逻辑 playerOne - playerTwo == 1在这里就总结出来感觉有点早
- 第九个TDD cycle (deuce) 和第八个有类似的问题
- - 我感觉第九个TDD cycle 应该再写一个 advantage 的测试, 比如 5比4. 一方面, advantage这个问题并没有解决完. 另一方面, 从 Transformation Priority Premise (TPP) 的角度来说, deuce 对应的 transformation 是 unconditional -> if, 而再写一个 advantage 的测试对应的 transformation 应该是 statement -> statements (playerOne == 4 -> playerOne == 4 || playerOne == 5). 后者的优先级更高一些
- - 前面提到了, deuce 不应该是 4比4, 而是 3比3
+ 第十个TDD cycle (player two win) 中最后重构好的代码还是很精彩的, 去掉了那些 if的重复代码, 很简洁.
- - 最后的代码中我还建议做一个重构, 就是把 playerTwo 领先和获胜的代码变成和 playerOne 领先和获胜的代码并列, 而不是嵌套. 修改后的代码大致如下:
if (playerOne >= 4 || playerTwo >= 4)
if (playerOne >= playerTwo)
return winnable(playerOne, playerTwo, “playerOne”);
else
return winnable(playerTwo, playerOne, “playerTwo”);
private static String winnable(…) {
return String.format(...)
}
原先的代码其实只会递归一次, 这种情况使用递归会比较奇怪, 因为一般的递归不会只执行一次, 容易让人产生误解. 另外 winnable 这个函数名修改成 scoreForDueceAndBeyond 之类的名字会好一些
和武可一样, 除了duece, 我也发现了那两个Bug
- 代码没有处理类似 2比1 的情况, 也就说如果 playerTwo 的得分不为0, 且不是 duece, advantage 和 win的情况, 都没有处理
- win的情况并没有都处理, 比如 4比1的测试会让代码失败
最后, 建议把最终代码也分享出来, 方便其他人在其基础上修改. :)
谢谢,
Joseph