




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、L/O/G/O 测试驱动开发测试驱动开发 敏捷开发培训系列敏捷开发培训系列 The Money实例实例 初步接触初步接触TDD 快速建立测试代码 运行测试代码,发现失败 做一个“小”调整 运行测试代码,使其全部成功 通过重构消除冗余 基本需求基本需求 实现一个多币种资金的功能实现一个多币种资金的功能 设备设备数量数量单价单价小计小计 IBM100025USD25000USD GE400100CHF60000CHF Total65000USD 货币货币1货币货币2汇率汇率 CHFUSD1.5 很简单的需求很简单的需求 好像没有什么难度好像没有什么难度 内容并不完全清晰内容并不完全清晰 如何作出最
2、优的设计如何作出最优的设计 让我们看让我们看TDD是怎样开始的是怎样开始的 Chapter 1开始开始 To-do list 导航员的主要工作导航员的主要工作 随时想到随时添加随时想到随时添加 从小步伐开始从小步伐开始 准备工作准备工作 创建一个创建一个Java项目项目 引用引用Junit类库类库 打包规则:打包规则:com.focoon.tdd Src目录为源文件目录目录为源文件目录 Test目录为测试文件目录目录为测试文件目录 To-do list $5+10CHF= $10 if rate is 2:1 $5*2=$10 不知道从哪开始?不知道从哪开始? 就从最基本的开始就从最基本的开始
3、 不用担心,以后想法会自然冒出来的不用担心,以后想法会自然冒出来的 找一个找一个To-do list开始开始 创建一个测试创建一个测试 public void testMultiplication() Dollar five = new Dollar (5); five.times(2); assertEquals(10, five.amount); 没有没脑的代码没有没脑的代码 编译都过不了编译都过不了 但是这就是开始但是这就是开始 让我们先运行测试,虽然肯定不会过让我们先运行测试,虽然肯定不会过 让我们来解决问题让我们来解决问题 创建创建Dollar类类 没有实现没有实现 但已经编译通过但
4、已经编译通过 运行测试,看结果,注意错误和失败的区别运行测试,看结果,注意错误和失败的区别 慢慢形成习惯慢慢形成习惯 public class Dollar int amount; Dollar(int amount) void times(int multiplier) 快速解决失败快速解决失败 成功!成功! 虽然没有解决问题,但是是有效的一部了 public class Dollar int amount = 10; Dollar(int amount) void times(int multiplier) 应用变量应用变量amount 仍然成功!仍然成功! public class Do
5、llar int amount = 10; Dollar(int amount) this.amount = amount; void times(int multiplier) amount *= 2; 应用变量应用变量multiplier 仍然成功!仍然成功! public class Dollar int amount = 10; Dollar(int amount) this.amount = amount; void times(int multiplier) amount *= multiplier; To-do list 又想到一些,至少有完成的: $5+10CHF= $10 i
6、f rate is 2:1 $5*2=$10 amount应该是私有的 Dollar side-effects 货币取整 到目前为止到目前为止 建立测试清单(建立测试清单(To-do list) 从乘法的小故事开始从乘法的小故事开始 暂时忽略暂时忽略Junit的细节的细节 通过缺省或略等方法让编译通过通过缺省或略等方法让编译通过 通过无赖的方法先让缺陷通过通过无赖的方法先让缺陷通过 逐步让代码通用化,把变量使用起来逐步让代码通用化,把变量使用起来 又扩展了一些新又扩展了一些新to-do list项项 参见参见Chapter 1-Answer Chapter 2变质的对象变质的对象 一个一个TD
7、D的过程如下的过程如下 写一个测试写一个测试 让它运行让它运行 让它正确让它正确 目标:可运行的干净代码目标:可运行的干净代码 The clean code that worksRon Jeffries 先让代码先让代码Work,再让它,再让它Clean To-do list 又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount应该是私有的 Dollar side-effects 货币取整 测试案例测试案例 换个数值,以防止写死代码的情况换个数值,以防止写死代码的情况 但失败了但失败了 找到原因找到原因 有时候修正的不一定是源程序
8、有时候修正的不一定是源程序 public void testMultiplication() Dollar five = new Dollar (5); five.times(2); assertEquals(10, five.amount); five.times(3); assertEquals(15, five.amount); 测试案例测试案例 引入一个变量引入一个变量 出现编译问题出现编译问题 继续解决问题继续解决问题 public void testMultiplication() Dollar five = new Dollar (5); Dollar product = fiv
9、e.times(2); assertEquals(10, product.amount); product = five.times(3); assertEquals(15, product.amount); Dollar 增加一个返回值增加一个返回值 先返回先返回null 编译通过但是失败了编译通过但是失败了 Dollar times(int multiplier) amount *= multiplier; return null; Dollar times(int multiplier) return new Dollar(amount * multiplier); 成功!成功! To-
10、do list 又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount应该是私有的 Dollar side-effects 货币取整 我们能让测试快速通过的方法我们能让测试快速通过的方法 我们已经用到了三个中的两个我们已经用到了三个中的两个 方法一:先写死,然后慢慢替换代码方法一:先写死,然后慢慢替换代码 方法二:直接写入实际代码方法二:直接写入实际代码 如果觉得复杂方法一,如果想清楚了方如果觉得复杂方法一,如果想清楚了方 法二法二 请参见请参见Chaper 2-Answer Chapter 3等于等于 To-do list 又想到
11、一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount应该是私有的 Dollar side-effects 货币取整 equals()方法方法 测试案例测试案例 失败失败 对应的实现类对应的实现类Dollar Fake public void testEquality() assertTrue(new Dollar(5).equals(new Dollar(5); public boolean equals(Object object) return true 追加案例挑战追加案例挑战Fake public void testEquali
12、ty() assertTrue(new Dollar(5).equals(new Dollar(5); assertFalse(new Dollar(5).equals(new Dollar(6); Dollar类类 定义定义equal:amount相等相等 将来可能会变化将来可能会变化 三角法三角法 public void testMultiplication() Dollar five = new Dollar (5); Dollar product = five.times(2); assertEquals(10, product.amount); product = five.time
13、s(3); assertEquals(15, product.amount); To-do list 又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount应该是私有的 Dollar side-effects 货币取整 equals()方法方法 equal空值的支持 equal对象 Chapter 4私有性私有性 To-do list 又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount应该是私有的应该是私有的 Dollar side-effects 货币取整 equa
14、ls()方法方法 equal空值的支持 equal对象 私有化的思路私有化的思路 将项目中直接调用之处改为私有调用将项目中直接调用之处改为私有调用 我们已经实现了对象的我们已经实现了对象的equals方法方法 public void testMultiplication() Dollar five = new Dollar (5); Dollar product = five.times(2); assertEquals(new Dollar(10), product); product = five.times(3); assertEquals(new Dollar(15), product
15、); 私有化的思路私有化的思路 临时变量没有用处了临时变量没有用处了 修改属性的私有化修改属性的私有化 public void testMultiplication() Dollar five = new Dollar (5); assertEquals(new Dollar(10), five.times(2); assertEquals(new Dollar(15), five.times(3); To-do list 又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount应该是私有的应该是私有的 Dollar side-eff
16、ects 货币取整 equals()方法方法 equal空值的支持 equal对象 Chapter 5引入法郎引入法郎 To-do list 又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount应该是私有的应该是私有的 Dollar side-effects 货币取整 equals()方法方法 equal空值的支持 equal对象 5CHF*2=10CHF,Franc side effects 先写先写Franc的测试的测试 复制粘贴一段测试代码,先复制粘贴一段测试代码,先 public void testFrancMultipl
17、ication() Franc five = new Franc (5); assertEquals(new Franc(10), five.times(2); assertEquals(new Franc(15), five.times(3); 再写再写Franc让测试通过让测试通过 复制粘贴一段复制粘贴一段Dollar代码,先代码,先 public class Franc private int amount; Franc(int amount) this.amount = amount; Franc times(int multiplier) return new Franc(amoun
18、t * multiplier); public boolean equals(Object object) Franc franc = (Franc)object; return amount = franc.amount; 消除冗余消除冗余 复制粘贴?冗余代码?缺乏抽象?复制粘贴?冗余代码?缺乏抽象? 消除冗余的重要性消除冗余的重要性 如果有冗余代码,在消除冗余前别给别如果有冗余代码,在消除冗余前别给别 人看到。除了结对伙伴人看到。除了结对伙伴 暂时放下,计入暂时放下,计入To-do list To-do list 又想到一些,至少有完成的: $5+10CHF= $10 if rate is
19、 2:1 $5*2=$10 amount应该是私有的应该是私有的 Dollar side-effects 货币取整 equals()方法方法 equal空值的支持 equal对象 5CHF*2=10CHF,Franc side effects Dollar/Franc的冗余问题 方法equals通用化 方法times通用化 Chapter 6一切均等一切均等 To-do list 又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount应该是私有的应该是私有的 Dollar side-effects 货币取整 equals()方法方法
20、 equal空值的支持 equal对象 5CHF*2=10CHF,Franc side effects Dollar/Franc的冗余问题 方法方法equals通用化通用化 方法times通用化 消除冗余消除冗余 消除上一阶段的欠账消除上一阶段的欠账 思路思路1 选一个类继承另一个选一个类继承另一个 结果上没有节省太多代码(可以试一下)结果上没有节省太多代码(可以试一下) 思路思路2 “找找”一个公共超类一个公共超类 例如例如Money 增加增加Money类类 Money public class Money Dollar继承继承Money public class Dollar extend
21、s Money private int amount; 移动属性移动属性amount Money,注意,注意protected public class Money protected int amount; Dollar public class Dollar extends Money Equals方法方法 将将equals方法改成能上移方法改成能上移 也就是也就是Money的的equals 现在现在Dollar里改里改 public boolean equals(Object object) Money money = (Money)object; return amount = mon
22、ey.amount; 再移动到再移动到Money中中 法郎的法郎的Equals方法方法 用于复制粘贴,法郎的用于复制粘贴,法郎的equals方法没有方法没有 测试,需要补上测试,需要补上 永远记住先写测试,再重构永远记住先写测试,再重构 public void testEquality() assertTrue(new Dollar(5).equals(new Dollar(5); assertFalse(new Dollar(5).equals(new Dollar(6); assertTrue(new Franc(5).equals(new Franc(5); assertFalse(ne
23、w Franc(5).equals(new Franc(6); 事实上我们又重复代码了事实上我们又重复代码了 先将法郎修改过来,记住先修改成一致先将法郎修改过来,记住先修改成一致 在删除冗余在删除冗余 To-do list 又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount应该是私有的应该是私有的 Dollar side-effects 货币取整 equals()方法方法 equal空值的支持 equal对象 5CHF*2=10CHF,Franc side effects Dollar/Franc的冗余问题 方法方法equals
24、通用化通用化 方法times通用化 Dollar和Franc的equals问题 Chapter 7当苹果遇到橘子当苹果遇到橘子 To-do list 又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount应该是私有的应该是私有的 Dollar side-effects 货币取整 equals()方法方法 equal空值的支持 equal对象 5CHF*2=10CHF,Franc side effects Dollar/Franc的冗余问题 方法方法equals通用化通用化 方法times通用化 Dollar和和Franc的的equa
25、ls问题问题 增加测试案例增加测试案例 首先测试不等首先测试不等 public void testEquality() assertTrue(new Dollar(5).equals(new Dollar(5); assertFalse(new Dollar(5).equals(new Dollar(6); assertTrue(new Franc(5).equals(new Franc(5); assertFalse(new Franc(5).equals(new Franc(6); assertFalse(new Franc(5).equals(new Dollar(5); 失败了,我们只
26、判断了金额失败了,我们只判断了金额 Equals方法方法 假定我们先使用类名来辅助判断相等,假定我们先使用类名来辅助判断相等, 虽然这有脱离了业务的虽然这有脱离了业务的“味道味道” 但我们还没有;类似币种的概念,所以但我们还没有;类似币种的概念,所以 权且用之权且用之 public boolean equals(Object object) Money money = (Money)object; return amount = money.amount To-do list 又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount应
27、该是私有的应该是私有的 Dollar side-effects 货币取整 equals()方法方法 equal空值的支持 equal对象 5CHF*2=10CHF,Franc side effects Dollar/Franc的冗余问题 方法方法equals通用化通用化 方法times通用化 Dollar和和Franc的的equals问题问题 引入币种的概念 Chapter 8制造对象制造对象 To-do list 又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount应该是私有的应该是私有的 Dollar side-effects
28、 货币取整 equals()方法方法 equal空值的支持 equal对象 5CHF*2=10CHF,Franc side effects Dollar/Franc的冗余问题(的冗余问题(times方法明显类同)方法明显类同) 方法方法equals通用化通用化 方法times通用化 Dollar和和Franc的的equals问题问题 引入币种的概念 类同的代码类同的代码 Dollar Franc Dollar times(int multiplier) return new Dollar(amount * multiplier); Franc times(int multiplier) ret
29、urn new Franc(amount * multiplier); 统一返回值统一返回值 Dollar Franc Money times(int multiplier) return new Dollar(amount * multiplier); Money times(int multiplier) return new Franc(amount * multiplier); 工厂方法替代工厂方法替代new 为了消除冗余我们先在为了消除冗余我们先在Money中引入一中引入一 个工厂方法可以返回个工厂方法可以返回Dollar,在测试中,在测试中 Money public void te
30、stMultiplication() Dollar five = Money.dollar(5); assertEquals(new Dollar(10), five.times(2); assertEquals(new Dollar(15), five.times(3); static Dollar dollar(int amount) return new Dollar(amount); 工厂方法替代工厂方法替代new 进一步我们是希望替换进一步我们是希望替换Dollar类,所以尝类,所以尝 试想试想Money靠近靠近 出错了,出错了,Money没有没有times方法,但其子方法,但其子
31、类有。先使用虚方法类有。先使用虚方法 public void testMultiplication() Money five = Money.dollar(5); assertEquals(new Dollar(10), five.times(2); assertEquals(new Dollar(15), five.times(3); public abstract class Money abstract Money times(int amount); 工厂方法替代工厂方法替代new 现在可以修改工厂方法的返回类了现在可以修改工厂方法的返回类了 static Money dollar(i
32、nt amount) return new Dollar(amount); 工厂方法替代工厂方法替代new 现在用工厂方法替代所有的现在用工厂方法替代所有的new方法方法 这样没有调用类需要知道有这样没有调用类需要知道有Dollar这个类这个类 了,记住为取出重复扫清道路了,记住为取出重复扫清道路 public void testMultiplication() Money five = Money.dollar(5); assertEquals(Money.dollar(10), five.times(2); assertEquals(Money.dollar(15), five.times
33、(3); public void testEquality() assertTrue(Money.dollar(5).equals(new Dollar(5); assertFalse(Money.dollar(5).equals(new Dollar(6); assertTrue(new Franc(5).equals(new Franc(5); assertFalse(new Franc(5).equals(new Franc(6); assertFalse(new Franc(5).equals(new Dollar(5); 工厂方法替代工厂方法替代new 同样的工作做在同样的工作做在F
34、ranc上,先测试上,先测试 public void testEquality() assertTrue(Money.dollar(5).equals(Money.dollar(5); assertFalse(Money.dollar(5).equals(Money.dollar(6); assertTrue(Money.franc(5).equals(Money.franc(5); assertFalse(Money.franc(5).equals(Money.franc(6); assertFalse(Money.franc(5).equals(Money.dollar(5); publi
35、c void testFrancMultiplication() Money five = Money.franc(5); assertEquals(Money.franc(10), five.times(2); assertEquals(Money.franc(15), five.times(3); 工厂方法替代工厂方法替代new 实现工厂方法,实现工厂方法,Money类类 static Money franc(int amount) return new Franc(amount); 看起来看起来Dollar和和Franc分别测试的案例重分别测试的案例重 复了,但是消除案例的重复不是简单的
36、复了,但是消除案例的重复不是简单的 删除案例,否则会带来测试不足的隐患,删除案例,否则会带来测试不足的隐患, 所以我们先记下这个问题。所以我们先记下这个问题。 To-do list 又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount应该是私有的应该是私有的 Dollar side-effects 货币取整 equals()方法方法 equal空值的支持 equal对象 5CHF*2=10CHF,Franc side effects Dollar/Franc的冗余问题的冗余问题 方法方法equals通用化通用化 方法times通用
37、化 Dollar和和Franc的的equals问题问题 引入币种的概念 去除重复的testFrancMultiplicaion案例 Chapter 9多币种多币种 To-do list 又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount应该是私有的应该是私有的 Dollar side-effects 货币取整 equals()方法方法 equal空值的支持 equal对象 5CHF*2=10CHF,Franc side effects Dollar/Franc的冗余问题 方法方法equals通用化通用化 方法times通用化 D
38、ollar和和Franc的的equals问题问题 引入币种的概念(用最简单的字符串表示币种)引入币种的概念(用最简单的字符串表示币种) 去除重复的testFrancMultiplicaion案例 增加测试案例增加测试案例 USD和和CHF public void testCurrency() assertEquals(USD, Money.dollar(1).currency(); assertEquals(CHF, Money.franc(1).currency(); 实现多币种实现多币种 先和先和times一样处理,一样处理,Money abstract String currency()
39、; Dollar String currency() return USD; Franc String currency() return CHF; 实现多币种实现多币种 将币种作为一个属性可能更合理将币种作为一个属性可能更合理 做相应的调整,做相应的调整,Dollar private String currency; Dollar(int amount) this.amount = amount; currency = USD; String currency() return currency; 实现多币种实现多币种 Franc 又重复,我忍又重复,我忍 private String cu
40、rrency; Franc(int amount) this.amount = amount; currency = “CHF; String currency() return currency; 实现多币种实现多币种 将重复的将重复的currency属性归纳到属性归纳到Money中中 protected String currency; String currency() return currency; 构造函数的微调构造函数的微调 如果把构造函数中币种字符串替换为变如果把构造函数中币种字符串替换为变 量,那么两个构造函数内容就一致了量,那么两个构造函数内容就一致了 以此为目标,先价格参
41、数,以此为目标,先价格参数,Franc开始开始 Franc(int amount, String currency) this.amount = amount; currency = CHF; 构造函数的微调构造函数的微调 调用构造函数的地方出错了,调用构造函数的地方出错了,Money static Money franc(int amount) return new Franc(amount, null); Franc Money times(int multiplier) return new Franc(amount * multiplier, null); 突然发现突然发现times用
42、的是用的是new而不是工厂方而不是工厂方 法,一般不要打断现在的工作,先写入法,一般不要打断现在的工作,先写入 To-do List,不过这里就先改了,不过这里就先改了 构造函数的微调构造函数的微调 测试失败了,需要将币种字符串引测试失败了,需要将币种字符串引 入入,Franc Franc(int amount, String currency) this.amount = amount; this.currency = currency; Money static Money franc(int amount) return new Franc(amount, CHF); 心得心得 通过细小
43、的变化可以使推进更加可靠通过细小的变化可以使推进更加可靠 但是否一直保持这样细小的步伐?但是否一直保持这样细小的步伐? 答案是:不答案是:不 只是需要有能力细小化只是需要有能力细小化 如果有信心就迈开大步,如果复杂了就如果有信心就迈开大步,如果复杂了就 缩小步伐,就像汽车起步挂档一样。缩小步伐,就像汽车起步挂档一样。 构造函数的微调构造函数的微调 同样的工作在同样的工作在Dollar上,我们又闻到上,我们又闻到“味味 道道”了了 Money static Money dollar(int amount) return new Dollar(amount, “USD); Dollar(int a
44、mount, String currency) this.amount = amount; this.currency = currency; Money times(int multiplier) return Money.dollar(amount * multiplier); 构造函数的上移构造函数的上移 既然构造函数一致,就可以上移,既然构造函数一致,就可以上移,Money Dollar Dollar(int amount, String currency) super(amount, currency); Money(int amount, String currency) this
45、.amount = amount; this.currency = currency; Franc Franc(int amount, String currency) super(amount, currency); To-do list 又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount应该是私有的应该是私有的 Dollar side-effects 货币取整 equals()方法方法 equal空值的支持 equal对象 5CHF*2=10CHF,Franc side effects Dollar/Franc的冗余问题 方
46、法方法equals通用化通用化 方法times通用化 Dollar和和Franc的的equals问题问题 引入币种的概念(用最简单的字符串表示币种)引入币种的概念(用最简单的字符串表示币种) 去除重复的testFrancMultiplicaion案例 Chapter 10乘法的处理乘法的处理 To-do list 又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount应该是私有的应该是私有的 Dollar side-effects 货币取整 equals()方法方法 equal空值的支持 equal对象 5CHF*2=10CHF,F
47、ranc side effects Dollar/Franc的冗余问题 方法方法equals通用化通用化 方法方法times通用化通用化 Dollar和和Franc的的equals问题问题 引入币种的概念(用最简单的字符串表示币种)引入币种的概念(用最简单的字符串表示币种) 去除重复的testFrancMultiplicaion案例 两个相似的乘法两个相似的乘法 相似但不相同,相似但不相同,Franc Dollar Money times(int multiplier) return Money.franc(amount * multiplier); Money times(int multi
48、plier) return Money.dollar(amount * multiplier); 没有明显的方法使其相同没有明显的方法使其相同 有时候需要采取以退为进的策略有时候需要采取以退为进的策略 回到回到new 相似但不相同,相似但不相同,Franc Dollar Money times(int multiplier) return new Franc(amount * multiplier, “CHF”); Money times(int multiplier) return new Dollar(amount * multiplier, USD); 没有明显的方法使其相同没有明显的方
49、法使其相同 有时候需要采取以退为进的策略有时候需要采取以退为进的策略 回到回到new 我们也可以使用我们也可以使用currency属性,这样两属性,这样两 个方法更接近写,个方法更接近写,Franc Dollar Money times(int multiplier) return new Franc(amount * multiplier, currency); Money times(int multiplier) return new Dollar(amount * multiplier, currency); 如果用如果用Money会怎样?会怎样? 我们总是尝试让实现趋同,我们总是尝试
50、让实现趋同,Franc Money times(int multiplier) return new Money(amount * multiplier, currency); 编译器说编译器说Money是个虚类是个虚类 实化实化Money 从最简单的开始,从最简单的开始,Money public class Money Money times(int amount) return null; 两个看不懂的失败两个看不懂的失败 好象是对象比较的问题,先修改对象输好象是对象比较的问题,先修改对象输 出,出,Money 实化实化Money Money的的toString方法方法 没有测试代码?没有
51、测试代码? 这里这里toString只用于只用于debug,风险低,风险低 当我们在红杠状态时我们倾向于不额外当我们在红杠状态时我们倾向于不额外 写测试代码写测试代码 通过新的通过新的toString我们看到内容是一致的我们看到内容是一致的 问题出在之前采用的类判断上问题出在之前采用的类判断上 public String toString() return amount + + currency; 退回退回 为了解决上述问题我们需要改代码为了解决上述问题我们需要改代码 但当我们在红杠状态时,我们不能写且但当我们在红杠状态时,我们不能写且 他测试代码他测试代码 而没有测试代码我们就不能修改新代码
52、而没有测试代码我们就不能修改新代码 所以正确的做法是退回所以正确的做法是退回 Money times(int multiplier) return new Franc(amount * multiplier, currency); 现在可以写测试了现在可以写测试了 判断不同类的币种相同判断不同类的币种相同 public void testDifferentClassEquality() assertTrue(new Money(10, CHF).equals(new Franc(10, CHF); 修改修改Equals方法方法 从判断类到判断币种字符串,从判断类到判断币种字符串, Money
53、public boolean equals(Object object) Money money = (Money)object; return amount = money.amount 再次尝试用再次尝试用Money Franc Money times(int multiplier) return new Money(amount * multiplier, currency); 成功,而且代码一样,合并到成功,而且代码一样,合并到Money Dollar Money times(int multiplier) return new Money(amount * multiplier, c
54、urrency); Money times(int multiplier) return new Money(amount * multiplier, currency); To-do list 又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount应该是私有的应该是私有的 Dollar side-effects 货币取整 equals()方法方法 equal空值的支持 equal对象 5CHF*2=10CHF,Franc side effects Dollar/Franc的冗余问题 方法方法equals通用化通用化 方法方法tim
55、es通用化通用化 Dollar和和Franc的的equals问题问题 引入币种的概念(用最简单的字符串表示币种)引入币种的概念(用最简单的字符串表示币种) 去除重复的testFrancMultiplicaion案例 Chapter 11只有只有Money To-do list 又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount应该是私有的应该是私有的 Dollar side-effects 货币取整 equals()方法方法 equal空值的支持 equal对象 5CHF*2=10CHF,Franc side effects D
56、ollar/Franc的冗余问题(只剩下构造函数了)的冗余问题(只剩下构造函数了) 方法方法equals通用化通用化 方法方法times通用化通用化 Dollar和和Franc的的equals问题问题 引入币种的概念(用最简单的字符串表示币种)引入币种的概念(用最简单的字符串表示币种) 去除重复的testFrancMultiplicaion案例 构造函数构造函数 尝试替换对构造函数的调用,尝试替换对构造函数的调用,Money 没有对没有对Dollar类的调用了,可以直接删掉类的调用了,可以直接删掉 了了 static Money dollar(int amount) return new Mo
57、ney(amount, USD); static Money franc(int amount) return new Money(amount, CHF); 删除删除Franc 对对Franc类还有一处引用类还有一处引用 但是离开但是离开Franc类,这个测试就和另一个类,这个测试就和另一个 测试等价了测试等价了 public void testDifferentClassEquality() assertTrue(new Money(10, CHF).equals(new Franc(10, CHF); public void testEquality() assertTrue(Money
58、.dollar(5).equals(Money.dollar(5); assertFalse(Money.dollar(5).equals(Money.dollar(6); assertTrue(Money.franc(5).equals(Money.franc(5); assertFalse(Money.franc(5).equals(Money.franc(6); assertFalse(Money.franc(5).equals(Money.dollar(5); 删除多余的测试删除多余的测试 删除对删除对Franc类还有一处引用的测试类还有一处引用的测试 删除等价测试删除等价测试 pub
59、lic void testDifferentClassEquality() public void testFrancMultiplication() public void testEquality() assertTrue(Money.dollar(5).equals(Money.dollar(5); assertFalse(Money.dollar(5).equals(Money.dollar(6); /assertTrue(Money.franc(5).equals(Money.franc(5); /assertFalse(Money.franc(5).equals(Money.fra
60、nc(6) ; assertFalse(Money.franc(5).equals(Money.dollar(5); To-do list 又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount应该是私有的应该是私有的 Dollar side-effects 货币取整 equals()方法方法 hashCode equal空值的支持 equal对象 5CHF*2=10CHF,Franc side effects Dollar/Franc的冗余问题的冗余问题 方法方法equals通用化通用化 方法方法times通用化通用化 Dolla
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 网络普法考试试题及答案
- 工程招投标管理与协议执行流程规范
- 浙江国企招聘2025温州市瓯海旅游投资集团有限公司及下属子公司招聘10人笔试参考题库附带答案详解
- 2025福建福州市建筑大数据技术有限公司招聘4人笔试参考题库附带答案详解
- 2025河南郑州二七区一国企招聘各部门人员9人笔试参考题库附带答案详解
- 2025江苏徐州东创新能源科技有限公司招聘19人笔试参考题库附带答案详解
- 2025年合肥兴泰金融控股(集团)有限公司招聘23人笔试参考题库附带答案详解
- 2025山东芳蕾玫瑰科技开发有限公司招聘11人笔试参考题库附带答案详解
- 幼儿园秋游安全教案
- 合作协议书和合同
- 消防文职考试试题及答案
- 2024年甘肃兰州事业单位考试真题
- 2025年导游从业资格通关秘籍
- 中国法院知识产权司法保护状况2024
- 小学语文古诗词教学策略探究
- 2025年4月《粉尘涉爆重大事故隐患解读》应急部
- 四川省绵阳市2025届高三下学期第三次诊断性测试数学试卷(含答案)
- 智能界面布局研究-全面剖析
- 当代中国外交(外交学院)知到智慧树章节测试课后答案2024年秋外交学院
- 《机械制造技术基础》期末考试试卷及答案
- 小学科学湘科版六年级下册全册同步练习含答案
评论
0/150
提交评论