标签
| TDD Java
字数
| 1474字
阅读
| 4分钟
说明:
本讲义是我在ThoughtWorks作为咨询师时,为客户开展TDD Code Kata而编写。案例为Guess Number,案例需求来自当时的同事王瑜珩。当时,我们共同在ThoughtWorks的Zynx交付团队,为培养团队TDD能力进行训练时,引入了本案例。讲义中给出的代码问题则来自客户方的受训学员,可谓“真实的代码坏味道”。个人认为TDD不只是开发方法,还应该是设计方法,因此讲义中包含了诸多设计原理、思想和原则。
目标收益
-
熟悉IDE快捷键;
-
掌握TDD基本知识;
-
识别代码坏味道,熟练运用重构手法;
-
熟悉JUnit与Mockito框架;
-
了解Google Guice框架;
我们对Guess Number分解的任务为:
开始第三个任务
之所以将“验证输入是否合法”放在第三个任务,是因为它不属于happy path的范畴。它属于辅助业务,重要性相对次之。
提示:对于第三个任务,可以采用Specification By Example的方式来考虑测试用例。
问题:参数 vs. 字段
学员在定义执行该任务的类时,一种可能性是将输入的答案作为类的构造函数参数。例如:
new InputValidator("1 2 3 5").validate();
存在两个错误:
-
错误地判断了输入值的生命周期。什么内容应该放在构造函数中作为参数?换言之,构造函数参数与对象之间的关系是什么?之所以要作为构造函数参数,就是意味着在某种场景下这些参数值应该在创建该对象时就存在。这些参数值与对象“生死与共”,它们的生命周期是保持一致的。如果不是,就不应该作为构造函数的参数。你觉得输入应该作为构造函数吗?如果我要验证另一条输入应该怎么办?再创建一个InputValidator对象吗?
-
违反了阅读直觉。validate()方法验证谁?验证空吗?显然这样的接口违反了主-谓-宾的语法。
问题:封装的Answer与输入
既然已经封装了Answer对象,为何validate()方法还是要接收字符串类型的输入?阅读需求,已可寻求到答案。