专栏名称: 逸言
文学与软件,诗意地想念。
目录
相关文章推荐
程序员的那些事  ·  DeepSeek 下棋靠忽悠赢了 ... ·  18 小时前  
OSC开源社区  ·  继V3之后,沐曦GPU再完成DeepSeek ... ·  昨天  
程序员小灰  ·  这款AI编程工具,将会取代Cursor! ·  昨天  
程序员小灰  ·  疯了!下载 DeepSeek 最高判20年! ·  4 天前  
程序猿  ·  450万虚假Star曝光,最低0.7元/个? ... ·  3 天前  
51好读  ›  专栏  ›  逸言

一个完整的TDD演练案例(三)

逸言  · 公众号  · 程序员  · 2018-10-10 16:25

正文

标签 | TDD Java

字数 | 1474字

阅读 | 4分钟


说明: 本讲义是我在ThoughtWorks作为咨询师时,为客户开展TDD Code Kata而编写。案例为Guess Number,案例需求来自当时的同事王瑜珩。当时,我们共同在ThoughtWorks的Zynx交付团队,为培养团队TDD能力进行训练时,引入了本案例。讲义中给出的代码问题则来自客户方的受训学员,可谓“真实的代码坏味道”。个人认为TDD不只是开发方法,还应该是设计方法,因此讲义中包含了诸多设计原理、思想和原则。

目标收益

  • 熟悉IDE快捷键;

  • 掌握TDD基本知识;

  • 识别代码坏味道,熟练运用重构手法;

  • 熟悉JUnit与Mockito框架;

  • 了解Google Guice框架;


我们对Guess Number分解的任务为:

  • 随机生成答案

  • 判断每次猜测的结果

  • 检查输入是否合法

  • 记录并显示历史猜测数据

  • 判断游戏结果。判断猜测次数,如果满6次但是未猜对则判负;如果在6次内猜测的4个数字值与位置都正确,则判胜



开始第三个任务


之所以将“验证输入是否合法”放在第三个任务,是因为它不属于happy path的范畴。它属于辅助业务,重要性相对次之。


提示:对于第三个任务,可以采用Specification By Example的方式来考虑测试用例。


问题:参数 vs. 字段


学员在定义执行该任务的类时,一种可能性是将输入的答案作为类的构造函数参数。例如:

new InputValidator("1 2 3 5").validate();


存在两个错误:

  • 错误地判断了输入值的生命周期。什么内容应该放在构造函数中作为参数?换言之,构造函数参数与对象之间的关系是什么?之所以要作为构造函数参数,就是意味着在某种场景下这些参数值应该在创建该对象时就存在。这些参数值与对象“生死与共”,它们的生命周期是保持一致的。如果不是,就不应该作为构造函数的参数。你觉得输入应该作为构造函数吗?如果我要验证另一条输入应该怎么办?再创建一个InputValidator对象吗?

  • 违反了阅读直觉。validate()方法验证谁?验证空吗?显然这样的接口违反了主-谓-宾的语法。


问题:封装的Answer与输入


既然已经封装了Answer对象,为何validate()方法还是要接收字符串类型的输入?阅读需求,已可寻求到答案。







请到「今天看啥」查看全文