加入收藏 | 设为首页 | 会员中心 | 我要投稿 安卓应用网 (https://www.0791zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 程序设计 > 正文

《Test-Driven development By Example》阅读(二)

发布时间:2020-05-23 16:18:52 所属栏目:程序设计 来源:互联网
导读:第四章 变质的对象(Degenerate Objects)——使用数值对象(value object),不必担心别名问题。 1、clean code that works! 要达到这一目标,可以分步实施: 先达到“that works”,在达到“clean code”。——这与“体系结构驱动开发”相反! 第五章 众生

第四章 变质的对象(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()方法: publicclassDollar{ publicintamount=0; publicDollar(intamount){ this.amount=amount; } publicDollartimes(intmultiplier){ returnnewDollar(amount*multiplier); } publicbooleanequals(Objectobject){ Dollardollar=(Dollar)object; returnamount==dollar.amount; } } 对equals()方法书写测试代码: publicclasstestDollarextendsTestCase{ publicvoidtestMultiplication(){ Dollarfive=newDollar(5); Dollarproduct=five.times(2); assertEquals(10,product.amount); product=five.times(3); assertEquals(15,product.amount); } publicvoidtestEquality(){ assertTrue(newDollar(5).equals(newDollar(5))); assertFalse(newDollar(5).equals(newDollar(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)让对象之间进行比较; publicclasstestDollarextendsTestCase{ publicvoidtestMultiplication(){ Dollarfive=newDollar(5); assertEquals(newDollar(10),five.times(2)); assertEquals(newDollar(15),five.times(3)); } publicvoidtestEquality(){ assertTrue(newDollar(5).equals(newDollar(5))); assertFalse(newDollar(5).equals(newDollar(6))); } } 经过修改,现在Dollar类是唯一个使用实例变量amount的类,可以把amount 设为private。 修改Dollar类代码: publicclassDollar{ privateintamount=0; publicDollar(intamount){ this.amount=amount; } publicDollartimes(intmultiplier){ returnnewDollar(amount*multiplier); } publicbooleanequals(Objectobject){ Dollardollar=(Dollar)object; returnamount==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一样的类以及方法: publicclassFranc{ privateintamount=0; publicFranc(intamount){ this.amount=amount; } publicFranctimes(intmultiplier){ returnnewFranc(amount*multiplier); } publicbooleanequals(Objectobject){ Francdollar=(Franc)object; returnamount==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代码如下: publicclassMoney{ protectedintamount=0; publicbooleanequals(Objectobject){ Moneymoney=(Money)object; returnamount==money.amount; } } 子类Franc代码如下: publicclassFrancextendsMoney{ publicFranc(intamount){ this.amount=amount; } publicFranctimes(intmultiplier){ returnnewFranc(amount*multiplier); } } 子类Dollar代码如下: publicclassDollarextendsMoney{ publicDollar(intamount){ this.amount=amount; } publicDollartimes(intmultiplier){ returnnewDollar(amount*multiplier); } } 测试代码不作任何变化: publicclasstestDollarextendsTestCase{ publicvoidtestMultiplication(){ Dollarfive=newDollar(5); assertEquals(newDollar(10),five.times(3)); } publicvoidtestEquality(){ assertTrue(newDollar(5).equals(newDollar(5))); assertFalse(newDollar(5).equals(newDollar(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两个对象 publicclasstestDollarextendsTestCase{ publicvoidtestMultiplication(){ Dollarfive=newDollar(5); assertEquals(newDollar(10),five.times(3)); } publicvoidtestEquality(){ assertTrue(newDollar(5).equals(newDollar(5))); assertFalse(newDollar(5).equals(newDollar(6))); assertTrue(newFranc(5).equals(newFranc(5))); assertFalse(newFranc(5).equals(newFranc(6))); assertFalse(newFranc(5).equals(newDollar(5))); } } 测试失败!——表明当前的对象比较还存在问题! 新引入问题: (14)对象之间的判等; (15)货币表示? (2)继续修改equals()代码,并进行断点调试,结果如下: publicclassMoney{ protectedintamount=0; publicbooleanequals(Objectobject){ Moneymoney=(Money)object; returnamount==money.amount &&getClass().equals(money.getClass()); } }
分析语句 assertFalse(newFranc(5).equals(newDollar(5))): 其中 newFranc(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类: publicabstractclassMoney{ protectedintamount=0; publicbooleanequals(Objectobject){ Moneymoney=(Money)object; returnamount==money.amount &&getClass().equals(money.getClass()); } publicstaticDollardollar(intamount){ returnnewDollar(amount); } publicstaticFrancfranc(intamount){ returnnewFranc(amount); } publicabstractMoneytimes(intmultiplier); } 修改后的Dollar类和Franc类: publicclassDollarextendsMoney{ publicDollar(intamount){ this.amount=amount; } publicMoneytimes(intmultiplier){ returnnewDollar(amount*multiplier); } } publicclassFrancextendsMoney{ publicFranc(intamount){ this.amount=amount; } publicMoneytimes(intmultiplier){ returnnewFranc(amount*multiplier); } } 修改后的测试代码: publicclasstestDollarextendsTestCase{ publicvoidtestMultiplication(){ Moneyfive=Money.dollar(5); assertEquals(Money.dollar(10),five.times(2)); assertEquals(Money.dollar(15),five.times(3)); } publicvoidtestEquality(){ assertTrue(Money.dollar(5).equals(newDollar(5))); assertFalse(Money.dollar(5).equals(newDollar(6))); assertTrue(Money.franc(5).equals(newFranc(5))); assertFalse(Money.franc(5).equals(newFranc(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)增加货币属性; publicabstractclassMoney{ protectedintamount=0; protectedStringcurrancy; publicMoney(intamount,Stringcurrancy){ this.amount=amount; this.currancy=currancy; } publicstaticDollardollar(intamount){ returnnewDollar(amount,"USD"); } publicstaticFrancfranc(intamount){ returnnewFranc(amount,"CHF"); } publicabstractMoneytimes(intmultiplier); publicbooleanequals(Objectobject){ Moneymoney=(Money)object; returnamount==money.amount &&getClass().equals(money.getClass()); } publicStringcurrancy(){ returncurrancy; } } publicclassFrancextendsMoney{ publicFranc(intamount,Stringcurrancy){ super(amount,currancy); } publicMoneytimes(intmultiplier){ returnMoney.franc(amount*multiplier); } } publicclassDollarextendsMoney{ publicDollar(intamount,currancy); } publicMoneytimes(intmultiplier){ returnMoney.dollar(amount*multiplier); } } publicclasstestDollarextendsTestCase{ publicvoidtestMultiplication(){ Moneyfive=Money.dollar(5); assertEquals(Money.dollar(10),five.times(2)); assertEquals(Money.dollar(15),five.times(3)); } publicvoidtestCurrancy(){ 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方法到父类中: publicclassMoney{ protectedintamount=0; protectedStringcurrancy; publicMoney(intamount,Stringcurrancy){ this.amount=amount; this.currancy=currancy; } publicstaticDollardollar(intamount){ returnnewDollar(amount,"USD"); } publicstaticFrancfranc(intamount){ returnnewFranc(amount,"CHF"); } publicMoneytimes(intmultiplier){ returnnewMoney(amount*multiplier,currancy); } publicbooleanequals(Objectobject){ Moneymoney=(Money)object; returnamount==money.amount &&this.currancy.equals(money.currancy()); } publicStringcurrancy(){ returncurrancy; } } publicclassFrancextendsMoney{ publicFranc(intamount,Stringcurrancy){ super(amount,currancy); } } publicclassDollarextendsMoney{ publicDollar(intamount,currancy); } } publicclasstestDollarextendsTestCase{ publicvoidtestMultiplication(){ Moneyfive=Money.dollar(5); assertEquals(Money.dollar(10),five.times(2)); assertEquals(Money.dollar(15),five.times(3)); } publicvoidtestCurrancy(){ assertEquals("USD",Money.dollar(1).currancy()); assertEquals("CHF",Money.franc(1).currancy()); } } 测试通过!

(编辑:安卓应用网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读