《Test-Driven development By Example》阅读(二)
2013-07-05 15:45
525 查看
第四章 变质的对象(Degenerate Objects)——使用数值对象(value object),不必担心别名问题。
1、clean code that works!
要达到这一目标,可以分步实施:先达到“that works”,在达到“clean code”。——这与“体系结构驱动开发”相反!
第五章 众生平等(Equality for All)——解决判等问题:equals()
1、三角法——或称为“间接法”
只有当例子达到2个或者更多时才对代码进行一般化。
2、存在的问题:
(1)汇率转换问题,当汇率为2:1时,5美元 + 10法郎 = 10美元;
(2)5美元 * 2 = 10美元;
(3)将amount定义为私有;
(4)Dollar类有副作用吗?
(5)钱数为整数;
(6)实现equals()函数;——拟解决问题
(7)实现hashCode()函数;
(8)与空对象判等;
(9)与非同类对象判等;
(10)5法郎 * 2 = 10法郎;
3、同步工程实践:
重写Dollar类中equals()方法:
public class Dollar {
public int amount = 0;
public Dollar(int amount) {
this.amount = amount;
}
public Dollar times(int multiplier) {
return new Dollar(amount*multiplier);
}
public boolean equals(Object object){
Dollar dollar = (Dollar)object;
return amount == dollar.amount;
}
}
对equals()方法书写测试代码:
public class testDollar extends TestCase {
public void testMultiplication(){
Dollar five = new Dollar(5);
Dollar product = five.times(2);
assertEquals(10,product.amount);
product=five.times(3);
assertEquals(15,product.amount);
}
public void testEquality(){
assertTrue(new Dollar(5).equals(new Dollar(5)));
assertFalse(new Dollar(5).equals(new Dollar(6)));
}
}
测试通过,消除问题(6)。
第六章 私有性(privacy)——把公有变成私有
1、存在的问题:
(1)汇率转换问题,当汇率为2:1时,5美元 + 10法郎 = 10美元;
(2)5美元 * 2 = 10美元;
(3)将amount定义为私有;——待解决问题
(4)Dollar类有副作用吗?
(5)钱数为整数;
(6)实现equals()函数;
(7)实现hashCode()函数;
(8)与空对象判等;
(9)与非同类对象判等;
(10)5法郎 * 2 = 10法郎;
2、同步工程实践:
对原有测试代码进行调整,引入内联(inline)语句:
(1)去除原来的product对象,同时消除了product对amount的引用;
(2)让对象之间进行比较;
public class testDollar extends TestCase {
public void testMultiplication(){
Dollar five = new Dollar(5);
assertEquals(new Dollar(10),five.times(2));
assertEquals(new Dollar(15),five.times(3));
}
public void testEquality(){
assertTrue(new Dollar(5).equals(new Dollar(5)));
assertFalse(new Dollar(5).equals(new Dollar(6)));
}
}
经过修改,现在Dollar类是唯一个使用实例变量amount的类,可以把amount设为private。
修改Dollar类代码:
public class Dollar {
private int amount = 0;
public Dollar(int amount) {
this.amount = amount;
}
public Dollar times(int multiplier) {
return new Dollar(amount*multiplier);
}
public boolean equals(Object object){
Dollar dollar = (Dollar)object;
return amount == dollar.amount;
}
}
若直接修改Dollar类amount为私有,不进行测试代码修改,则会出错:
java中访问私有变量只能使用getter()和setter()!
第七章 法郎在诉说(Franc-ly Speaking)——处理法郎问题
1、存在的问题:
(1)汇率转换问题,当汇率为2:1时,5美元 + 10法郎 = 10美元;
(2)5美元 * 2 = 10美元;
(3)将amount定义为私有;
(4)Dollar类有副作用吗?
(5)钱数为整数;
(6)实现equals()函数;
(7)实现hashCode()函数;
(8)与空对象判等;
(9)与非同类对象判等;
(10)5法郎 * 2 = 10法郎;——待解决问题
2、同步工程实践:
建立同dollar一样的类以及方法:
public class Franc {
private int amount = 0;
public Franc(int amount) {
this.amount = amount;
}
public Franc times(int multiplier) {
return new Franc(amount*multiplier);
}
public boolean equals(Object object){
Franc dollar = (Franc)object;
return amount == dollar.amount;
}
}
这样就完成了问题(10),但同时新增加了三个问题!
(11)Dollar与Franc之间的重复设计问题;
(12)普通判等;
(13)普通相乘;
第八章 再议众生平等(Equality for All:Redux)——解决判等问题
1、存在的问题:
(1)汇率转换问题,当汇率为2:1时,5美元 + 10法郎 = 10美元;
(2)5美元 * 2 = 10美元;
(3)将amount定义为私有;
(4)Dollar类有副作用吗?
(5)钱数为整数;
(6)实现equals()函数;
(7)实现hashCode()函数;
(8)与空对象判等;
(9)与非同类对象判等;
(10)5法郎 * 2 = 10法郎;
(11)Dollar与Franc之间的重复设计问题;
(12)普通判等;——待解决问题
(13)普通相乘;
2、同步工程实践:
(1)抽取父类Money,使Dollar和Franc都继承Money;
(2)把子类公共代码抽取到父类;——在父类Money中声明amount为protected,以便子类能够看到。
(3)把equals()方法上移到父类中;
父类Money代码如下:
public class Money {
protected int amount = 0;
public boolean equals(Object object){
Money money = (Money)object;
return amount == money.amount;
}
}
子类Franc代码如下:
public class Franc extends Money{
public Franc(int amount) {
this.amount = amount;
}
public Franc times(int multiplier) {
return new Franc(amount*multiplier);
}
}
子类Dollar代码如下:
public class Dollar extends Money{
public Dollar(int amount) {
this.amount = amount;
}
public Dollar times(int multiplier) {
return new Dollar(amount*multiplier);
}
}
测试代码不作任何变化:
public class testDollar extends TestCase {
public void testMultiplication(){
Dollar five = new Dollar(5);
assertEquals(new Dollar(10),five.times(2));
assertEquals(new Dollar(15),five.times(3));
}
public void testEquality(){
assertTrue(new Dollar(5).equals(new Dollar(5)));
assertFalse(new Dollar(5).equals(new Dollar(6)));
}
}
第九章 苹果和橘子(Apples and Oranges)——两个对象的判等问题(数值和类均相等时才相等)
1、存在的问题:
(1)汇率转换问题,当汇率为2:1时,5美元 + 10法郎 = 10美元;
(2)5美元 * 2 = 10美元;
(3)将amount定义为私有;
(4)Dollar类有副作用吗?
(5)钱数为整数;
(6)实现equals()函数;
(7)实现hashCode()函数;
(8)与空对象判等;
(9)与非同类对象判等;
(10)5法郎 * 2 = 10法郎;
(11)Dollar与Franc之间的重复设计问题;
(12)普通判等;
(13)普通相乘;
2、同步工程实践:
(1)进一步修改测试代码,比较Dollar和Franc两个对象
public class testDollar extends TestCase {
public void testMultiplication(){
Dollar five = new Dollar(5);
assertEquals(new Dollar(10),five.times(2));
assertEquals(new Dollar(15),five.times(3));
}
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)));
}
}
测试失败!——表明当前的对象比较还存在问题!
新引入问题:
(14)对象之间的判等;
(15)货币表示?
(2)继续修改equals()代码,并进行断点调试,结果如下:
public class Money {
protected int amount = 0;
public boolean equals(Object object){
Money money = (Money)object;
return amount == money.amount
&& getClass().equals(money.getClass());
}
}
分析语句assertFalse(new Franc(5).equals(new Dollar(5))):
其中new Franc(5).equals()中equals()调用继承自父类Money的方法,其中getClass()返回值为Franc实例的类型Franc;而参数中money.getClass()返回的是Dollar实例的类型类Dollar。
第十章 制造对象(Makin' Objects)——使用工厂方法制造对象
1、存在的问题:
(1)汇率转换问题,当汇率为2:1时,5美元 + 10法郎 = 10美元;
(2)5美元 * 2 = 10美元;
(3)将amount定义为私有;
(4)Dollar类有副作用吗?
(5)钱数为整数;
(6)实现equals()函数;
(7)实现hashCode()函数;
(8)与空对象判等;
(9)与非同类对象判等;
(10)5法郎 * 2 = 10法郎;
(11)Dollar与Franc之间的重复设计问题;
(12)普通判等;
(13)普通相乘;
(14)对象之间的判等;
(15)货币表示?
2、同步工程实践:
(1)主要是对两个子类中极为相似的times()函数进行修改;
修改后的Money类:
public abstract class Money {
protected int amount = 0;
public boolean equals(Object object){
Money money = (Money)object;
return amount == money.amount
&& getClass().equals(money.getClass());
}
public static Dollar dollar(int amount) {
return new Dollar(amount);
}
public static Franc franc(int amount) {
return new Franc(amount);
}
public abstract Money times(int multiplier);
}
修改后的Dollar类和Franc类:
public class Dollar extends Money{
public Dollar(int amount) {
this.amount = amount;
}
public Money times(int multiplier) {
return new Dollar(amount*multiplier);
}
}
public class Franc extends Money{
public Franc(int amount) {
this.amount = amount;
}
public Money times(int multiplier) {
return new Franc(amount*multiplier);
}
}
修改后的测试代码:
public class testDollar extends TestCase {
public void testMultiplication(){
Money five = Money.dollar(5);
assertEquals(Money.dollar(10),five.times(2));
assertEquals(Money.dollar(15),five.times(3));
}
public void testEquality(){
assertTrue(Money.dollar(5).equals(new Dollar(5)));
assertFalse(Money.dollar(5).equals(new Dollar(6)));
assertTrue(Money.franc(5).equals(new Franc(5)));
assertFalse(Money.franc(5).equals(new Franc(6)));
assertFalse(Money.franc(5).equals(Money.dollar(5)));
}
}
下一步消除times()的重复设计!
第十一章 我们所处的时代(Times we are live in)——消除times()重复设计!
1、存在的问题:
(1)汇率转换问题,当汇率为2:1时,5美元 + 10法郎 = 10美元;
(2)5美元 * 2 = 10美元;
(3)将amount定义为私有;
(4)Dollar类有副作用吗?
(5)钱数为整数;
(6)实现equals()函数;
(7)实现hashCode()函数;
(8)与空对象判等;
(9)与非同类对象判等;
(10)5法郎 * 2 = 10法郎;
(11)Dollar与Franc之间的重复设计问题;
(12)普通判等;
(13)普通相乘;
(14)对象之间的判等;
(15)货币表示?
2、同步工程实践:
(1)增加货币属性;
public abstract class Money {
protected int amount = 0;
protected String currancy;
public Money(int amount, String currancy) {
this.amount = amount;
this.currancy = currancy;
}
public static Dollar dollar(int amount) {
return new Dollar(amount,"USD");
}
public static Franc franc(int amount) {
return new Franc(amount,"CHF");
}
public abstract Money times(int multiplier);
public boolean equals(Object object){
Money money = (Money)object;
return amount == money.amount
&& getClass().equals(money.getClass());
}
public String currancy(){
return currancy;
}
}
public class Franc extends Money{
public Franc(int amount, String currancy) {
super(amount, currancy);
}
public Money times(int multiplier) {
return Money.franc(amount*multiplier);
}
}
public class Dollar extends Money{
public Dollar(int amount, String currancy) {
super(amount,currancy);
}
public Money times(int multiplier) {
return Money.dollar(amount*multiplier);
}
}
public class testDollar extends TestCase {
public void testMultiplication(){
Money five = Money.dollar(5);
assertEquals(Money.dollar(10),five.times(2));
assertEquals(Money.dollar(15),five.times(3));
}
public void testCurrancy(){
assertEquals("USD",Money.dollar(1).currancy());
assertEquals("CHF",Money.franc(1).currancy());
}
}
第十二章 有趣的Times方法(Interesting Times)——消除times()重复设计!
1、存在的问题:
(1)汇率转换问题,当汇率为2:1时,5美元 + 10法郎 = 10美元;
(2)5美元 * 2 = 10美元;
(3)将amount定义为私有;
(4)Dollar类有副作用吗?
(5)钱数为整数;
(6)实现equals()函数;
(7)实现hashCode()函数;
(8)与空对象判等;
(9)与非同类对象判等;
(10)5法郎 * 2 = 10法郎;
(11)Dollar与Franc之间的重复设计问题;
(12)普通判等;
(13)普通相乘;
(14)对象之间的判等;
(15)货币表示?
2、同步工程实践:
提取times方法到父类中:
public class Money {
protected int amount = 0;
protected String currancy;
public Money(int amount, String currancy) {
this.amount = amount;
this.currancy = currancy;
}
public static Dollar dollar(int amount) {
return new Dollar(amount,"USD");
}
public static Franc franc(int amount) {
return new Franc(amount,"CHF");
}
public Money times(int multiplier){
return new Money(amount*multiplier,currancy);
}
public boolean equals(Object object){
Money money = (Money)object;
return amount == money.amount
&& this.currancy.equals(money.currancy());
}
public String currancy(){
return currancy;
}
}
public class Franc extends Money{
public Franc(int amount, String currancy) {
super(amount, currancy);
}
}
public class Dollar extends Money{
public Dollar(int amount, String currancy) {
super(amount,currancy);
}
}
public class testDollar extends TestCase {
public void testMultiplication(){
Money five = Money.dollar(5);
assertEquals(Money.dollar(10),five.times(2));
assertEquals(Money.dollar(15),five.times(3));
}
public void testCurrancy(){
assertEquals("USD",Money.dollar(1).currancy());
assertEquals("CHF",Money.franc(1).currancy());
}
}
测试通过!
1、clean code that works!
要达到这一目标,可以分步实施:先达到“that works”,在达到“clean code”。——这与“体系结构驱动开发”相反!
第五章 众生平等(Equality for All)——解决判等问题:equals()
1、三角法——或称为“间接法”
只有当例子达到2个或者更多时才对代码进行一般化。
2、存在的问题:
(1)汇率转换问题,当汇率为2:1时,5美元 + 10法郎 = 10美元;
(2)5美元 * 2 = 10美元;
(3)将amount定义为私有;
(4)Dollar类有副作用吗?
(5)钱数为整数;
(6)实现equals()函数;——拟解决问题
(7)实现hashCode()函数;
(8)与空对象判等;
(9)与非同类对象判等;
(10)5法郎 * 2 = 10法郎;
3、同步工程实践:
重写Dollar类中equals()方法:
public class Dollar {
public int amount = 0;
public Dollar(int amount) {
this.amount = amount;
}
public Dollar times(int multiplier) {
return new Dollar(amount*multiplier);
}
public boolean equals(Object object){
Dollar dollar = (Dollar)object;
return amount == dollar.amount;
}
}
对equals()方法书写测试代码:
public class testDollar extends TestCase {
public void testMultiplication(){
Dollar five = new Dollar(5);
Dollar product = five.times(2);
assertEquals(10,product.amount);
product=five.times(3);
assertEquals(15,product.amount);
}
public void testEquality(){
assertTrue(new Dollar(5).equals(new Dollar(5)));
assertFalse(new Dollar(5).equals(new Dollar(6)));
}
}
测试通过,消除问题(6)。
第六章 私有性(privacy)——把公有变成私有
1、存在的问题:
(1)汇率转换问题,当汇率为2:1时,5美元 + 10法郎 = 10美元;
(2)5美元 * 2 = 10美元;
(3)将amount定义为私有;——待解决问题
(4)Dollar类有副作用吗?
(5)钱数为整数;
(6)实现equals()函数;
(7)实现hashCode()函数;
(8)与空对象判等;
(9)与非同类对象判等;
(10)5法郎 * 2 = 10法郎;
2、同步工程实践:
对原有测试代码进行调整,引入内联(inline)语句:
(1)去除原来的product对象,同时消除了product对amount的引用;
(2)让对象之间进行比较;
public class testDollar extends TestCase {
public void testMultiplication(){
Dollar five = new Dollar(5);
assertEquals(new Dollar(10),five.times(2));
assertEquals(new Dollar(15),five.times(3));
}
public void testEquality(){
assertTrue(new Dollar(5).equals(new Dollar(5)));
assertFalse(new Dollar(5).equals(new Dollar(6)));
}
}
经过修改,现在Dollar类是唯一个使用实例变量amount的类,可以把amount设为private。
修改Dollar类代码:
public class Dollar {
private int amount = 0;
public Dollar(int amount) {
this.amount = amount;
}
public Dollar times(int multiplier) {
return new Dollar(amount*multiplier);
}
public boolean equals(Object object){
Dollar dollar = (Dollar)object;
return amount == dollar.amount;
}
}
若直接修改Dollar类amount为私有,不进行测试代码修改,则会出错:
java中访问私有变量只能使用getter()和setter()!
第七章 法郎在诉说(Franc-ly Speaking)——处理法郎问题
1、存在的问题:
(1)汇率转换问题,当汇率为2:1时,5美元 + 10法郎 = 10美元;
(2)5美元 * 2 = 10美元;
(3)将amount定义为私有;
(4)Dollar类有副作用吗?
(5)钱数为整数;
(6)实现equals()函数;
(7)实现hashCode()函数;
(8)与空对象判等;
(9)与非同类对象判等;
(10)5法郎 * 2 = 10法郎;——待解决问题
2、同步工程实践:
建立同dollar一样的类以及方法:
public class Franc {
private int amount = 0;
public Franc(int amount) {
this.amount = amount;
}
public Franc times(int multiplier) {
return new Franc(amount*multiplier);
}
public boolean equals(Object object){
Franc dollar = (Franc)object;
return amount == dollar.amount;
}
}
这样就完成了问题(10),但同时新增加了三个问题!
(11)Dollar与Franc之间的重复设计问题;
(12)普通判等;
(13)普通相乘;
第八章 再议众生平等(Equality for All:Redux)——解决判等问题
1、存在的问题:
(1)汇率转换问题,当汇率为2:1时,5美元 + 10法郎 = 10美元;
(2)5美元 * 2 = 10美元;
(3)将amount定义为私有;
(4)Dollar类有副作用吗?
(5)钱数为整数;
(6)实现equals()函数;
(7)实现hashCode()函数;
(8)与空对象判等;
(9)与非同类对象判等;
(10)5法郎 * 2 = 10法郎;
(11)Dollar与Franc之间的重复设计问题;
(12)普通判等;——待解决问题
(13)普通相乘;
2、同步工程实践:
(1)抽取父类Money,使Dollar和Franc都继承Money;
(2)把子类公共代码抽取到父类;——在父类Money中声明amount为protected,以便子类能够看到。
(3)把equals()方法上移到父类中;
父类Money代码如下:
public class Money {
protected int amount = 0;
public boolean equals(Object object){
Money money = (Money)object;
return amount == money.amount;
}
}
子类Franc代码如下:
public class Franc extends Money{
public Franc(int amount) {
this.amount = amount;
}
public Franc times(int multiplier) {
return new Franc(amount*multiplier);
}
}
子类Dollar代码如下:
public class Dollar extends Money{
public Dollar(int amount) {
this.amount = amount;
}
public Dollar times(int multiplier) {
return new Dollar(amount*multiplier);
}
}
测试代码不作任何变化:
public class testDollar extends TestCase {
public void testMultiplication(){
Dollar five = new Dollar(5);
assertEquals(new Dollar(10),five.times(2));
assertEquals(new Dollar(15),five.times(3));
}
public void testEquality(){
assertTrue(new Dollar(5).equals(new Dollar(5)));
assertFalse(new Dollar(5).equals(new Dollar(6)));
}
}
第九章 苹果和橘子(Apples and Oranges)——两个对象的判等问题(数值和类均相等时才相等)
1、存在的问题:
(1)汇率转换问题,当汇率为2:1时,5美元 + 10法郎 = 10美元;
(2)5美元 * 2 = 10美元;
(3)将amount定义为私有;
(4)Dollar类有副作用吗?
(5)钱数为整数;
(6)实现equals()函数;
(7)实现hashCode()函数;
(8)与空对象判等;
(9)与非同类对象判等;
(10)5法郎 * 2 = 10法郎;
(11)Dollar与Franc之间的重复设计问题;
(12)普通判等;
(13)普通相乘;
2、同步工程实践:
(1)进一步修改测试代码,比较Dollar和Franc两个对象
public class testDollar extends TestCase {
public void testMultiplication(){
Dollar five = new Dollar(5);
assertEquals(new Dollar(10),five.times(2));
assertEquals(new Dollar(15),five.times(3));
}
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)));
}
}
测试失败!——表明当前的对象比较还存在问题!
新引入问题:
(14)对象之间的判等;
(15)货币表示?
(2)继续修改equals()代码,并进行断点调试,结果如下:
public class Money {
protected int amount = 0;
public boolean equals(Object object){
Money money = (Money)object;
return amount == money.amount
&& getClass().equals(money.getClass());
}
}
分析语句assertFalse(new Franc(5).equals(new Dollar(5))):
其中new Franc(5).equals()中equals()调用继承自父类Money的方法,其中getClass()返回值为Franc实例的类型Franc;而参数中money.getClass()返回的是Dollar实例的类型类Dollar。
第十章 制造对象(Makin' Objects)——使用工厂方法制造对象
1、存在的问题:
(1)汇率转换问题,当汇率为2:1时,5美元 + 10法郎 = 10美元;
(2)5美元 * 2 = 10美元;
(3)将amount定义为私有;
(4)Dollar类有副作用吗?
(5)钱数为整数;
(6)实现equals()函数;
(7)实现hashCode()函数;
(8)与空对象判等;
(9)与非同类对象判等;
(10)5法郎 * 2 = 10法郎;
(11)Dollar与Franc之间的重复设计问题;
(12)普通判等;
(13)普通相乘;
(14)对象之间的判等;
(15)货币表示?
2、同步工程实践:
(1)主要是对两个子类中极为相似的times()函数进行修改;
修改后的Money类:
public abstract class Money {
protected int amount = 0;
public boolean equals(Object object){
Money money = (Money)object;
return amount == money.amount
&& getClass().equals(money.getClass());
}
public static Dollar dollar(int amount) {
return new Dollar(amount);
}
public static Franc franc(int amount) {
return new Franc(amount);
}
public abstract Money times(int multiplier);
}
修改后的Dollar类和Franc类:
public class Dollar extends Money{
public Dollar(int amount) {
this.amount = amount;
}
public Money times(int multiplier) {
return new Dollar(amount*multiplier);
}
}
public class Franc extends Money{
public Franc(int amount) {
this.amount = amount;
}
public Money times(int multiplier) {
return new Franc(amount*multiplier);
}
}
修改后的测试代码:
public class testDollar extends TestCase {
public void testMultiplication(){
Money five = Money.dollar(5);
assertEquals(Money.dollar(10),five.times(2));
assertEquals(Money.dollar(15),five.times(3));
}
public void testEquality(){
assertTrue(Money.dollar(5).equals(new Dollar(5)));
assertFalse(Money.dollar(5).equals(new Dollar(6)));
assertTrue(Money.franc(5).equals(new Franc(5)));
assertFalse(Money.franc(5).equals(new Franc(6)));
assertFalse(Money.franc(5).equals(Money.dollar(5)));
}
}
下一步消除times()的重复设计!
第十一章 我们所处的时代(Times we are live in)——消除times()重复设计!
1、存在的问题:
(1)汇率转换问题,当汇率为2:1时,5美元 + 10法郎 = 10美元;
(2)5美元 * 2 = 10美元;
(3)将amount定义为私有;
(4)Dollar类有副作用吗?
(5)钱数为整数;
(6)实现equals()函数;
(7)实现hashCode()函数;
(8)与空对象判等;
(9)与非同类对象判等;
(10)5法郎 * 2 = 10法郎;
(11)Dollar与Franc之间的重复设计问题;
(12)普通判等;
(13)普通相乘;
(14)对象之间的判等;
(15)货币表示?
2、同步工程实践:
(1)增加货币属性;
public abstract class Money {
protected int amount = 0;
protected String currancy;
public Money(int amount, String currancy) {
this.amount = amount;
this.currancy = currancy;
}
public static Dollar dollar(int amount) {
return new Dollar(amount,"USD");
}
public static Franc franc(int amount) {
return new Franc(amount,"CHF");
}
public abstract Money times(int multiplier);
public boolean equals(Object object){
Money money = (Money)object;
return amount == money.amount
&& getClass().equals(money.getClass());
}
public String currancy(){
return currancy;
}
}
public class Franc extends Money{
public Franc(int amount, String currancy) {
super(amount, currancy);
}
public Money times(int multiplier) {
return Money.franc(amount*multiplier);
}
}
public class Dollar extends Money{
public Dollar(int amount, String currancy) {
super(amount,currancy);
}
public Money times(int multiplier) {
return Money.dollar(amount*multiplier);
}
}
public class testDollar extends TestCase {
public void testMultiplication(){
Money five = Money.dollar(5);
assertEquals(Money.dollar(10),five.times(2));
assertEquals(Money.dollar(15),five.times(3));
}
public void testCurrancy(){
assertEquals("USD",Money.dollar(1).currancy());
assertEquals("CHF",Money.franc(1).currancy());
}
}
第十二章 有趣的Times方法(Interesting Times)——消除times()重复设计!
1、存在的问题:
(1)汇率转换问题,当汇率为2:1时,5美元 + 10法郎 = 10美元;
(2)5美元 * 2 = 10美元;
(3)将amount定义为私有;
(4)Dollar类有副作用吗?
(5)钱数为整数;
(6)实现equals()函数;
(7)实现hashCode()函数;
(8)与空对象判等;
(9)与非同类对象判等;
(10)5法郎 * 2 = 10法郎;
(11)Dollar与Franc之间的重复设计问题;
(12)普通判等;
(13)普通相乘;
(14)对象之间的判等;
(15)货币表示?
2、同步工程实践:
提取times方法到父类中:
public class Money {
protected int amount = 0;
protected String currancy;
public Money(int amount, String currancy) {
this.amount = amount;
this.currancy = currancy;
}
public static Dollar dollar(int amount) {
return new Dollar(amount,"USD");
}
public static Franc franc(int amount) {
return new Franc(amount,"CHF");
}
public Money times(int multiplier){
return new Money(amount*multiplier,currancy);
}
public boolean equals(Object object){
Money money = (Money)object;
return amount == money.amount
&& this.currancy.equals(money.currancy());
}
public String currancy(){
return currancy;
}
}
public class Franc extends Money{
public Franc(int amount, String currancy) {
super(amount, currancy);
}
}
public class Dollar extends Money{
public Dollar(int amount, String currancy) {
super(amount,currancy);
}
}
public class testDollar extends TestCase {
public void testMultiplication(){
Money five = Money.dollar(5);
assertEquals(Money.dollar(10),five.times(2));
assertEquals(Money.dollar(15),five.times(3));
}
public void testCurrancy(){
assertEquals("USD",Money.dollar(1).currancy());
assertEquals("CHF",Money.franc(1).currancy());
}
}
测试通过!
相关文章推荐
- 《Test-Driven development By Example》阅读(三)
- 《Test-Driven development By Example》阅读(一)
- Test - Driven Development By Example 测试驱动开发 (读书笔记)
- Test Driven Development: By Example
- A question when reading Test Driven Development - A J2EE Example
- Test-Driven Development In .NET 部分译文
- Test Driven Development
- 翻译 Test-Driven Development in Microsoft .NET
- 关于CS169 TDD(Test Driven Development)
- [导入]Test-Driven Development in .NET
- VisualStudio2010-Test Driven Development(二)
- TDD Test Driven Development 测试驱动开发
- 敏捷(AM):TDD(Test Driven Development)实践与变化-->TAD(Test Assist Development)
- vs2008软件测试实战 2 test driven development
- [导入]Test-Driven Development in .NET
- Test driven development and The value object pattern
- Test-Driven Development and Testing Early
- Test Driven Development
- 【转】Test Driven Development (TDD)介绍
- vs2008软件测试实战 2 test driven development