火龍果-測(cè)試驅(qū)動(dòng)開(kāi)發(fā)_第1頁(yè)
火龍果-測(cè)試驅(qū)動(dòng)開(kāi)發(fā)_第2頁(yè)
火龍果-測(cè)試驅(qū)動(dòng)開(kāi)發(fā)_第3頁(yè)
火龍果-測(cè)試驅(qū)動(dòng)開(kāi)發(fā)_第4頁(yè)
火龍果-測(cè)試驅(qū)動(dòng)開(kāi)發(fā)_第5頁(yè)
已閱讀5頁(yè),還剩149頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、L/O/G/O測(cè)試驅(qū)動(dòng)開(kāi)發(fā)測(cè)試驅(qū)動(dòng)開(kāi)發(fā)敏捷開(kāi)發(fā)培訓(xùn)系列敏捷開(kāi)發(fā)培訓(xùn)系列 The Money實(shí)例實(shí)例 初步接觸初步接觸TDD 快速建立測(cè)試代碼 運(yùn)行測(cè)試代碼,發(fā)現(xiàn)失敗 做一個(gè)“小”調(diào)整 運(yùn)行測(cè)試代碼,使其全部成功 通過(guò)重構(gòu)消除冗余 基本需求基本需求 實(shí)現(xiàn)一個(gè)多幣種資金的功能實(shí)現(xiàn)一個(gè)多幣種資金的功能設(shè)備設(shè)備數(shù)量數(shù)量單價(jià)單價(jià)小計(jì)小計(jì)IBM100025USD25000USDGE400100CHF60000CHFTotal65000USD貨幣貨幣1貨幣貨幣2匯率匯率CHFUSD1.5 很簡(jiǎn)單的需求很簡(jiǎn)單的需求 好像沒(méi)有什么難度好像沒(méi)有什么難度 內(nèi)容并不完全清晰內(nèi)容并不完全清晰 如何作出最優(yōu)的設(shè)計(jì)如何作出

2、最優(yōu)的設(shè)計(jì) 讓我們看讓我們看TDD是怎樣開(kāi)始的是怎樣開(kāi)始的 Chapter 1開(kāi)始開(kāi)始 To-do list 導(dǎo)航員的主要工作導(dǎo)航員的主要工作 隨時(shí)想到隨時(shí)添加隨時(shí)想到隨時(shí)添加 從小步伐開(kāi)始從小步伐開(kāi)始 準(zhǔn)備工作準(zhǔn)備工作 創(chuàng)建一個(gè)創(chuàng)建一個(gè)Java項(xiàng)目項(xiàng)目 引用引用Junit類(lèi)庫(kù)類(lèi)庫(kù) 打包規(guī)則:打包規(guī)則:com.focoon.tdd Src目錄為源文件目錄目錄為源文件目錄 Test目錄為測(cè)試文件目錄目錄為測(cè)試文件目錄 To-do list $5+10CHF= $10 if rate is 2:1 $5*2=$10 不知道從哪開(kāi)始?不知道從哪開(kāi)始? 就從最基本的開(kāi)始就從最基本的開(kāi)始 不用擔(dān)心,以后

3、想法會(huì)自然冒出來(lái)的不用擔(dān)心,以后想法會(huì)自然冒出來(lái)的 找一個(gè)找一個(gè)To-do list開(kāi)始開(kāi)始 創(chuàng)建一個(gè)測(cè)試創(chuàng)建一個(gè)測(cè)試public void testMultiplication() Dollar five = new Dollar (5);five.times(2);assertEquals(10, five.amount); 沒(méi)有沒(méi)腦的代碼沒(méi)有沒(méi)腦的代碼 編譯都過(guò)不了編譯都過(guò)不了 但是這就是開(kāi)始但是這就是開(kāi)始 讓我們先運(yùn)行測(cè)試,雖然肯定不會(huì)過(guò)讓我們先運(yùn)行測(cè)試,雖然肯定不會(huì)過(guò) 讓我們來(lái)解決問(wèn)題讓我們來(lái)解決問(wèn)題 創(chuàng)建創(chuàng)建Dollar類(lèi)類(lèi) 沒(méi)有實(shí)現(xiàn)沒(méi)有實(shí)現(xiàn) 但已經(jīng)編譯通過(guò)但已經(jīng)編譯通過(guò) 運(yùn)行測(cè)試

4、,看結(jié)果,注意錯(cuò)誤和失敗的區(qū)別運(yùn)行測(cè)試,看結(jié)果,注意錯(cuò)誤和失敗的區(qū)別 慢慢形成習(xí)慣慢慢形成習(xí)慣public class Dollar int amount;Dollar(int amount) void times(int multiplier) 快速解決失敗快速解決失敗 成功!成功! 雖然沒(méi)有解決問(wèn)題,但是是有效的一部了public class Dollar int amount = 10;Dollar(int amount) void times(int multiplier) 應(yīng)用變量應(yīng)用變量amount 仍然成功!仍然成功!public class Dollar int amount

5、= 10;Dollar(int amount) this.amount = amount;void times(int multiplier) amount *= 2; 應(yīng)用變量應(yīng)用變量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 if rate is 2:1 $5*2=$10

6、 amount應(yīng)該是私有的 Dollar side-effects 貨幣取整 到目前為止到目前為止 建立測(cè)試清單(建立測(cè)試清單(To-do list) 從乘法的小故事開(kāi)始從乘法的小故事開(kāi)始 暫時(shí)忽略暫時(shí)忽略Junit的細(xì)節(jié)的細(xì)節(jié) 通過(guò)缺省或略等方法讓編譯通過(guò)通過(guò)缺省或略等方法讓編譯通過(guò) 通過(guò)無(wú)賴的方法先讓缺陷通過(guò)通過(guò)無(wú)賴的方法先讓缺陷通過(guò) 逐步讓代碼通用化,把變量使用起來(lái)逐步讓代碼通用化,把變量使用起來(lái) 又?jǐn)U展了一些新又?jǐn)U展了一些新to-do list項(xiàng)項(xiàng) 參見(jiàn)參見(jiàn)Chapter 1-Answer Chapter 2變質(zhì)的對(duì)象變質(zhì)的對(duì)象 一個(gè)一個(gè)TDD的過(guò)程如下的過(guò)程如下 寫(xiě)一個(gè)測(cè)試寫(xiě)一個(gè)測(cè)試

7、 讓它運(yùn)行讓它運(yùn)行 讓它正確讓它正確 目標(biāo):可運(yùn)行的干凈代碼目標(biāo):可運(yùn)行的干凈代碼 The clean code that worksRon Jeffries 先讓代碼先讓代碼Work,再讓它,再讓它Clean To-do list又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount應(yīng)該是私有的 Dollar side-effects 貨幣取整 測(cè)試案例測(cè)試案例 換個(gè)數(shù)值,以防止寫(xiě)死代碼的情況換個(gè)數(shù)值,以防止寫(xiě)死代碼的情況 但失敗了但失敗了 找到原因找到原因 有時(shí)候修正的不一定是源程序有時(shí)候修正的不一定是源程序public voi

8、d testMultiplication() Dollar five = new Dollar (5);five.times(2);assertEquals(10, five.amount);five.times(3);assertEquals(15, five.amount); 測(cè)試案例測(cè)試案例 引入一個(gè)變量引入一個(gè)變量 出現(xiàn)編譯問(wèn)題出現(xiàn)編譯問(wèn)題 繼續(xù)解決問(wèn)題繼續(xù)解決問(wèn)題public void testMultiplication() Dollar five = new Dollar (5);Dollar product = five.times(2);assertEquals(10, pr

9、oduct.amount);product = five.times(3);assertEquals(15, product.amount); Dollar 增加一個(gè)返回值增加一個(gè)返回值 先返回先返回null 編譯通過(guò)但是失敗了編譯通過(guò)但是失敗了Dollar times(int multiplier) amount *= multiplier;return null;Dollar times(int multiplier) return new Dollar(amount * multiplier); 成功!成功! To-do list又想到一些,至少有完成的: $5+10CHF= $10 i

10、f rate is 2:1 $5*2=$10 amount應(yīng)該是私有的 Dollar side-effects 貨幣取整 我們能讓測(cè)試快速通過(guò)的方法我們能讓測(cè)試快速通過(guò)的方法 我們已經(jīng)用到了三個(gè)中的兩個(gè)我們已經(jīng)用到了三個(gè)中的兩個(gè) 方法一:先寫(xiě)死,然后慢慢替換代碼方法一:先寫(xiě)死,然后慢慢替換代碼 方法二:直接寫(xiě)入實(shí)際代碼方法二:直接寫(xiě)入實(shí)際代碼 如果覺(jué)得復(fù)雜方法一,如果想清楚了方如果覺(jué)得復(fù)雜方法一,如果想清楚了方法二法二 請(qǐng)參見(jiàn)請(qǐng)參見(jiàn)Chaper 2-Answer Chapter 3等于等于 To-do list又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1

11、 $5*2=$10 amount應(yīng)該是私有的 Dollar side-effects 貨幣取整 equals()方法方法 測(cè)試案例測(cè)試案例 失敗失敗 對(duì)應(yīng)的實(shí)現(xiàn)類(lèi)對(duì)應(yīng)的實(shí)現(xiàn)類(lèi)Dollar Fakepublic void testEquality() assertTrue(new Dollar(5).equals(new Dollar(5);public boolean equals(Object object) return true 追加案例挑戰(zhàn)追加案例挑戰(zhàn)Fakepublic void testEquality() assertTrue(new Dollar(5).equals(new D

12、ollar(5); assertFalse(new Dollar(5).equals(new Dollar(6); Dollar類(lèi)類(lèi) 定義定義equal:amount相等相等 將來(lái)可能會(huì)變化將來(lái)可能會(huì)變化 三角法三角法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); To-do l

13、ist又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount應(yīng)該是私有的 Dollar side-effects 貨幣取整 equals()方法方法 equal空值的支持 equal對(duì)象 Chapter 4私有性私有性 To-do list又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount應(yīng)該是私有的應(yīng)該是私有的 Dollar side-effects 貨幣取整 equals()方法方法 equal空值的支持 equal對(duì)象 私有化的思路私有化的思路 將項(xiàng)目中直接調(diào)用

14、之處改為私有調(diào)用將項(xiàng)目中直接調(diào)用之處改為私有調(diào)用 我們已經(jīng)實(shí)現(xiàn)了對(duì)象的我們已經(jīng)實(shí)現(xiàn)了對(duì)象的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); 私有化的思路私有化的思路 臨時(shí)變量沒(méi)有用處了臨時(shí)變量沒(méi)有用處了 修改屬性的私有化修改屬性的私有化pub

15、lic 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應(yīng)該是私有的應(yīng)該是私有的 Dollar side-effects 貨幣取整 equals()方法方法 equal空值的支持 equal對(duì)象 Chapter 5引入法郎引入法

16、郎 To-do list又想到一些,至少有完成的: $5+10CHF= $10 if rate is 2:1 $5*2=$10 amount應(yīng)該是私有的應(yīng)該是私有的 Dollar side-effects 貨幣取整 equals()方法方法 equal空值的支持 equal對(duì)象 5CHF*2=10CHF,F(xiàn)ranc side effects 先寫(xiě)先寫(xiě)Franc的測(cè)試的測(cè)試 復(fù)制粘貼一段測(cè)試代碼,先復(fù)制粘貼一段測(cè)試代碼,先public void testFrancMultiplication() Franc five = new Franc (5);assertEquals(new Franc(

17、10), five.times(2);assertEquals(new Franc(15), five.times(3); 再寫(xiě)再寫(xiě)Franc讓測(cè)試通過(guò)讓測(cè)試通過(guò) 復(fù)制粘貼一段復(fù)制粘貼一段Dollar代碼,先代碼,先public class Franc private int amount;Franc(int amount) this.amount = amount;Franc times(int multiplier) return new Franc(amount * multiplier);public boolean equals(Object object) Franc franc

18、= (Franc)object;return amount = franc.amount; 消除冗余消除冗余 復(fù)制粘貼?冗余代碼?缺乏抽象?復(fù)制粘貼?冗余代碼?缺乏抽象? 消除冗余的重要性消除冗余的重要性 如果有冗余代碼,在消除冗余前別給別如果有冗余代碼,在消除冗余前別給別人看到。除了結(jié)對(duì)伙伴人看到。除了結(jié)對(duì)伙伴 暫時(shí)放下,計(jì)入暫時(shí)放下,計(jì)入To-do list To-do list又想到一些,至少有完成的:$5+10CHF= $10 if rate is 2:1$5*2=$10amount應(yīng)該是私有的應(yīng)該是私有的Dollar side-effects貨幣取整equals()方法方法equal

19、空值的支持equal對(duì)象5CHF*2=10CHF,F(xiàn)ranc side effectsDollar/Franc的冗余問(wèn)題方法equals通用化方法times通用化 Chapter 6一切均等一切均等 To-do list又想到一些,至少有完成的:$5+10CHF= $10 if rate is 2:1$5*2=$10amount應(yīng)該是私有的應(yīng)該是私有的Dollar side-effects貨幣取整equals()方法方法equal空值的支持equal對(duì)象5CHF*2=10CHF,F(xiàn)ranc side effectsDollar/Franc的冗余問(wèn)題方法方法equals通用化通用化方法times

20、通用化 消除冗余消除冗余 消除上一階段的欠賬消除上一階段的欠賬 思路思路1 選一個(gè)類(lèi)繼承另一個(gè)選一個(gè)類(lèi)繼承另一個(gè) 結(jié)果上沒(méi)有節(jié)省太多代碼(可以試一下)結(jié)果上沒(méi)有節(jié)省太多代碼(可以試一下) 思路思路2 “找找”一個(gè)公共超類(lèi)一個(gè)公共超類(lèi) 例如例如Money 增加增加Money類(lèi)類(lèi) Moneypublic class Money Dollar繼承繼承Moneypublic class Dollar extends Money private int amount; 移動(dòng)屬性移動(dòng)屬性amount Money,注意,注意protectedpublic class Money protected int

21、amount; Dollarpublic class Dollar extends Money Equals方法方法 將將equals方法改成能上移方法改成能上移 也就是也就是Money的的equals 現(xiàn)在現(xiàn)在Dollar里改里改public boolean equals(Object object) Money money = (Money)object;return amount = money.amount; 再移動(dòng)到再移動(dòng)到Money中中 法郎的法郎的Equals方法方法 用于復(fù)制粘貼,法郎的用于復(fù)制粘貼,法郎的equals方法沒(méi)有方法沒(méi)有測(cè)試,需要補(bǔ)上測(cè)試,需要補(bǔ)上 永遠(yuǎn)記住先寫(xiě)測(cè)

22、試,再重構(gòu)永遠(yuǎn)記住先寫(xiě)測(cè)試,再重構(gòu)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); 事實(shí)上我們又重復(fù)代碼了事實(shí)上我們又重復(fù)代碼了 先將法郎修改過(guò)來(lái),記住先修改成一致先將法郎修改過(guò)來(lái),記住先修改成一致在刪除冗余在刪除冗余 To-do

23、 list又想到一些,至少有完成的:$5+10CHF= $10 if rate is 2:1$5*2=$10amount應(yīng)該是私有的應(yīng)該是私有的Dollar side-effects貨幣取整equals()方法方法equal空值的支持equal對(duì)象5CHF*2=10CHF,F(xiàn)ranc side effectsDollar/Franc的冗余問(wèn)題方法方法equals通用化通用化方法times通用化Dollar和Franc的equals問(wèn)題 Chapter 7當(dāng)蘋(píng)果遇到橘子當(dāng)蘋(píng)果遇到橘子 To-do list又想到一些,至少有完成的:$5+10CHF= $10 if rate is 2:1$5*2=

24、$10amount應(yīng)該是私有的應(yīng)該是私有的Dollar side-effects貨幣取整equals()方法方法equal空值的支持equal對(duì)象5CHF*2=10CHF,F(xiàn)ranc side effectsDollar/Franc的冗余問(wèn)題方法方法equals通用化通用化方法times通用化Dollar和和Franc的的equals問(wèn)題問(wèn)題 增加測(cè)試案例增加測(cè)試案例 首先測(cè)試不等首先測(cè)試不等public void testEquality() assertTrue(new Dollar(5).equals(new Dollar(5);assertFalse(new Dollar(5).equ

25、als(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); 失敗了,我們只判斷了金額失敗了,我們只判斷了金額 Equals方法方法 假定我們先使用類(lèi)名來(lái)輔助判斷相等,假定我們先使用類(lèi)名來(lái)輔助判斷相等,雖然這有脫離了業(yè)務(wù)的雖然這有脫離了業(yè)務(wù)的“味道味道” 但我們還沒(méi)有;類(lèi)似幣種的概念,所以但我們還沒(méi)有;類(lèi)似幣種的概念,所以權(quán)且用之權(quán)且用之public

26、boolean equals(Object object) Money money = (Money)object;return amount = money.amount & getClass().equals(money.getClass(); To-do list又想到一些,至少有完成的:$5+10CHF= $10 if rate is 2:1$5*2=$10amount應(yīng)該是私有的應(yīng)該是私有的Dollar side-effects貨幣取整equals()方法方法equal空值的支持equal對(duì)象5CHF*2=10CHF,F(xiàn)ranc side effectsDollar/Franc的冗余

27、問(wèn)題方法方法equals通用化通用化方法times通用化Dollar和和Franc的的equals問(wèn)題問(wèn)題引入幣種的概念 Chapter 8制造對(duì)象制造對(duì)象 To-do list又想到一些,至少有完成的:$5+10CHF= $10 if rate is 2:1$5*2=$10amount應(yīng)該是私有的應(yīng)該是私有的Dollar side-effects貨幣取整equals()方法方法equal空值的支持equal對(duì)象5CHF*2=10CHF,F(xiàn)ranc side effectsDollar/Franc的冗余問(wèn)題(的冗余問(wèn)題(times方法明顯類(lèi)同)方法明顯類(lèi)同)方法方法equals通用化通用化方法

28、times通用化Dollar和和Franc的的equals問(wèn)題問(wèn)題引入幣種的概念 類(lèi)同的代碼類(lèi)同的代碼 Dollar FrancDollar times(int multiplier) return new Dollar(amount * multiplier);Franc times(int multiplier) return new Franc(amount * multiplier); 統(tǒng)一返回值統(tǒng)一返回值 Dollar FrancMoney times(int multiplier) return new Dollar(amount * multiplier);Money times

29、(int multiplier) return new Franc(amount * multiplier); 工廠方法替代工廠方法替代new 為了消除冗余我們先在為了消除冗余我們先在Money中引入一中引入一個(gè)工廠方法可以返回個(gè)工廠方法可以返回Dollar,在測(cè)試中,在測(cè)試中 Moneypublic void testMultiplication() Dollar five = Money.dollar(5);assertEquals(new Dollar(10), five.times(2);assertEquals(new Dollar(15), five.times(3);static

30、 Dollar dollar(int amount) return new Dollar(amount); 工廠方法替代工廠方法替代new 進(jìn)一步我們是希望替換進(jìn)一步我們是希望替換Dollar類(lèi),所以嘗類(lèi),所以嘗試想試想Money靠近靠近 出錯(cuò)了,出錯(cuò)了,Money沒(méi)有沒(méi)有times方法,但其子方法,但其子類(lèi)有。先使用虛方法類(lèi)有。先使用虛方法public void testMultiplication() Money five = Money.dollar(5);assertEquals(new Dollar(10), five.times(2);assertEquals(new Dollar

31、(15), five.times(3);public abstract class Moneyabstract Money times(int amount); 工廠方法替代工廠方法替代new 現(xiàn)在可以修改工廠方法的返回類(lèi)了現(xiàn)在可以修改工廠方法的返回類(lèi)了static Money dollar(int amount) return new Dollar(amount); 工廠方法替代工廠方法替代new 現(xiàn)在用工廠方法替代所有的現(xiàn)在用工廠方法替代所有的new方法方法 這樣沒(méi)有調(diào)用類(lèi)需要知道有這樣沒(méi)有調(diào)用類(lèi)需要知道有Dollar這個(gè)類(lèi)這個(gè)類(lèi)了,記住為取出重復(fù)掃清道路了,記住為取出重復(fù)掃清道路publ

32、ic 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(new Franc(5).equa

33、ls(new Franc(5);assertFalse(new Franc(5).equals(new Franc(6);assertFalse(new Franc(5).equals(new Dollar(5); 工廠方法替代工廠方法替代new 同樣的工作做在同樣的工作做在Franc上,先測(cè)試上,先測(cè)試public void testEquality() assertTrue(Money.dollar(5).equals(Money.dollar(5);assertFalse(Money.dollar(5).equals(Money.dollar(6);assertTrue(Money.fr

34、anc(5).equals(Money.franc(5);assertFalse(Money.franc(5).equals(Money.franc(6);assertFalse(Money.franc(5).equals(Money.dollar(5);public void testFrancMultiplication() Money five = Money.franc(5);assertEquals(Money.franc(10), five.times(2);assertEquals(Money.franc(15), five.times(3); 工廠方法替代工廠方法替代new 實(shí)

35、現(xiàn)工廠方法,實(shí)現(xiàn)工廠方法,Money類(lèi)類(lèi)static Money franc(int amount) return new Franc(amount); 看起來(lái)看起來(lái)Dollar和和Franc分別測(cè)試的案例重分別測(cè)試的案例重復(fù)了,但是消除案例的重復(fù)不是簡(jiǎn)單的復(fù)了,但是消除案例的重復(fù)不是簡(jiǎn)單的刪除案例,否則會(huì)帶來(lái)測(cè)試不足的隱患,刪除案例,否則會(huì)帶來(lái)測(cè)試不足的隱患,所以我們先記下這個(gè)問(wèn)題。所以我們先記下這個(gè)問(wèn)題。 To-do list又想到一些,至少有完成的:$5+10CHF= $10 if rate is 2:1$5*2=$10amount應(yīng)該是私有的應(yīng)該是私有的Dollar side-effe

36、cts貨幣取整equals()方法方法equal空值的支持equal對(duì)象5CHF*2=10CHF,F(xiàn)ranc side effectsDollar/Franc的冗余問(wèn)題的冗余問(wèn)題方法方法equals通用化通用化方法times通用化Dollar和和Franc的的equals問(wèn)題問(wèn)題引入幣種的概念去除重復(fù)的testFrancMultiplicaion案例 Chapter 9多幣種多幣種 To-do list又想到一些,至少有完成的:$5+10CHF= $10 if rate is 2:1$5*2=$10amount應(yīng)該是私有的應(yīng)該是私有的Dollar side-effects貨幣取整equals(

37、)方法方法equal空值的支持equal對(duì)象5CHF*2=10CHF,F(xiàn)ranc side effectsDollar/Franc的冗余問(wèn)題方法方法equals通用化通用化方法times通用化Dollar和和Franc的的equals問(wèn)題問(wèn)題引入幣種的概念(用最簡(jiǎn)單的字符串表示幣種)引入幣種的概念(用最簡(jiǎn)單的字符串表示幣種)去除重復(fù)的testFrancMultiplicaion案例 增加測(cè)試案例增加測(cè)試案例 USD和和CHFpublic void testCurrency() assertEquals(USD, Money.dollar(1).currency();assertEquals(C

38、HF, Money.franc(1).currency(); 實(shí)現(xiàn)多幣種實(shí)現(xiàn)多幣種 先和先和times一樣處理,一樣處理,Moneyabstract String currency(); DollarString currency() return USD; FrancString currency() return CHF; 實(shí)現(xiàn)多幣種實(shí)現(xiàn)多幣種 將幣種作為一個(gè)屬性可能更合理將幣種作為一個(gè)屬性可能更合理 做相應(yīng)的調(diào)整,做相應(yīng)的調(diào)整,Dollarprivate String currency;Dollar(int amount) this.amount = amount;currency =

39、USD;String currency() return currency; 實(shí)現(xiàn)多幣種實(shí)現(xiàn)多幣種 Franc 又重復(fù),我忍又重復(fù),我忍private String currency;Franc(int amount) this.amount = amount;currency = “CHF;String currency() return currency; 實(shí)現(xiàn)多幣種實(shí)現(xiàn)多幣種 將重復(fù)的將重復(fù)的currency屬性歸納到屬性歸納到Money中中protected String currency;String currency() return currency; 構(gòu)造函數(shù)的微調(diào)構(gòu)造函數(shù)的微

40、調(diào) 如果把構(gòu)造函數(shù)中幣種字符串替換為變?nèi)绻褬?gòu)造函數(shù)中幣種字符串替換為變量,那么兩個(gè)構(gòu)造函數(shù)內(nèi)容就一致了量,那么兩個(gè)構(gòu)造函數(shù)內(nèi)容就一致了 以此為目標(biāo),先價(jià)格參數(shù),以此為目標(biāo),先價(jià)格參數(shù),F(xiàn)ranc開(kāi)始開(kāi)始Franc(int amount, String currency) this.amount = amount;currency = CHF; 構(gòu)造函數(shù)的微調(diào)構(gòu)造函數(shù)的微調(diào) 調(diào)用構(gòu)造函數(shù)的地方出錯(cuò)了,調(diào)用構(gòu)造函數(shù)的地方出錯(cuò)了,Moneystatic Money franc(int amount) return new Franc(amount, null); FrancMoney times(

41、int multiplier) return new Franc(amount * multiplier, null); 突然發(fā)現(xiàn)突然發(fā)現(xiàn)times用的是用的是new而不是工廠方而不是工廠方法,一般不要打斷現(xiàn)在的工作,先寫(xiě)入法,一般不要打斷現(xiàn)在的工作,先寫(xiě)入To-do List,不過(guò)這里就先改了,不過(guò)這里就先改了 構(gòu)造函數(shù)的微調(diào)構(gòu)造函數(shù)的微調(diào) 測(cè)試失敗了,需要將幣種字符串引測(cè)試失敗了,需要將幣種字符串引入入,FrancFranc(int amount, String currency) this.amount = amount;this.currency = currency; Moneyst

42、atic Money franc(int amount) return new Franc(amount, CHF); 心得心得 通過(guò)細(xì)小的變化可以使推進(jìn)更加可靠通過(guò)細(xì)小的變化可以使推進(jìn)更加可靠 但是否一直保持這樣細(xì)小的步伐?但是否一直保持這樣細(xì)小的步伐? 答案是:不答案是:不 只是需要有能力細(xì)小化只是需要有能力細(xì)小化 如果有信心就邁開(kāi)大步,如果復(fù)雜了就如果有信心就邁開(kāi)大步,如果復(fù)雜了就縮小步伐,就像汽車(chē)起步掛檔一樣??s小步伐,就像汽車(chē)起步掛檔一樣。 構(gòu)造函數(shù)的微調(diào)構(gòu)造函數(shù)的微調(diào) 同樣的工作在同樣的工作在Dollar上,我們又聞到上,我們又聞到“味味道道”了了 Moneystatic Mone

43、y dollar(int amount) return new Dollar(amount, “USD);Dollar(int amount, String currency) this.amount = amount;this.currency = currency;Money times(int multiplier) return Money.dollar(amount * multiplier); 構(gòu)造函數(shù)的上移構(gòu)造函數(shù)的上移 既然構(gòu)造函數(shù)一致,就可以上移,既然構(gòu)造函數(shù)一致,就可以上移,Money DollarDollar(int amount, String currency) su

44、per(amount, currency);Money(int amount, String currency) this.amount = amount;this.currency = currency; FrancFranc(int amount, String currency) super(amount, currency); To-do list又想到一些,至少有完成的:$5+10CHF= $10 if rate is 2:1$5*2=$10amount應(yīng)該是私有的應(yīng)該是私有的Dollar side-effects貨幣取整equals()方法方法equal空值的支持equal對(duì)象5C

45、HF*2=10CHF,F(xiàn)ranc side effectsDollar/Franc的冗余問(wèn)題方法方法equals通用化通用化方法times通用化Dollar和和Franc的的equals問(wèn)題問(wèn)題引入幣種的概念(用最簡(jiǎn)單的字符串表示幣種)引入幣種的概念(用最簡(jiǎn)單的字符串表示幣種)去除重復(fù)的testFrancMultiplicaion案例 Chapter 10乘法的處理乘法的處理 To-do list又想到一些,至少有完成的:$5+10CHF= $10 if rate is 2:1$5*2=$10amount應(yīng)該是私有的應(yīng)該是私有的Dollar side-effects貨幣取整equals()方法

46、方法equal空值的支持equal對(duì)象5CHF*2=10CHF,F(xiàn)ranc side effectsDollar/Franc的冗余問(wèn)題方法方法equals通用化通用化方法方法times通用化通用化Dollar和和Franc的的equals問(wèn)題問(wèn)題引入幣種的概念(用最簡(jiǎn)單的字符串表示幣種)引入幣種的概念(用最簡(jiǎn)單的字符串表示幣種)去除重復(fù)的testFrancMultiplicaion案例 兩個(gè)相似的乘法兩個(gè)相似的乘法 相似但不相同,相似但不相同,F(xiàn)ranc DollarMoney times(int multiplier) return Money.franc(amount * multipli

47、er);Money times(int multiplier) return Money.dollar(amount * multiplier); 沒(méi)有明顯的方法使其相同沒(méi)有明顯的方法使其相同 有時(shí)候需要采取以退為進(jìn)的策略有時(shí)候需要采取以退為進(jìn)的策略 回到回到new 相似但不相同,相似但不相同,F(xiàn)ranc DollarMoney times(int multiplier) return new Franc(amount * multiplier, “CHF”);Money times(int multiplier) return new Dollar(amount * multiplier,

48、USD); 沒(méi)有明顯的方法使其相同沒(méi)有明顯的方法使其相同 有時(shí)候需要采取以退為進(jìn)的策略有時(shí)候需要采取以退為進(jìn)的策略 回到回到new 我們也可以使用我們也可以使用currency屬性,這樣兩屬性,這樣兩個(gè)方法更接近寫(xiě),個(gè)方法更接近寫(xiě),F(xiàn)ranc DollarMoney times(int multiplier) return new Franc(amount * multiplier, currency);Money times(int multiplier) return new Dollar(amount * multiplier, currency); 如果用如果用Money會(huì)怎樣?會(huì)怎樣

49、? 我們總是嘗試讓實(shí)現(xiàn)趨同,我們總是嘗試讓實(shí)現(xiàn)趨同,F(xiàn)rancMoney times(int multiplier) return new Money(amount * multiplier, currency); 編譯器說(shuō)編譯器說(shuō)Money是個(gè)虛類(lèi)是個(gè)虛類(lèi) 實(shí)化實(shí)化Money 從最簡(jiǎn)單的開(kāi)始,從最簡(jiǎn)單的開(kāi)始,Moneypublic class Money Money times(int amount) return null; 兩個(gè)看不懂的失敗兩個(gè)看不懂的失敗 好象是對(duì)象比較的問(wèn)題,先修改對(duì)象輸好象是對(duì)象比較的問(wèn)題,先修改對(duì)象輸出,出,Money 實(shí)化實(shí)化Money Money的的toStr

50、ing方法方法 沒(méi)有測(cè)試代碼?沒(méi)有測(cè)試代碼? 這里這里toString只用于只用于debug,風(fēng)險(xiǎn)低,風(fēng)險(xiǎn)低 當(dāng)我們?cè)诩t杠狀態(tài)時(shí)我們傾向于不額外當(dāng)我們?cè)诩t杠狀態(tài)時(shí)我們傾向于不額外寫(xiě)測(cè)試代碼寫(xiě)測(cè)試代碼 通過(guò)新的通過(guò)新的toString我們看到內(nèi)容是一致的我們看到內(nèi)容是一致的 問(wèn)題出在之前采用的類(lèi)判斷上問(wèn)題出在之前采用的類(lèi)判斷上public String toString() return amount + + currency; 退回退回 為了解決上述問(wèn)題我們需要改代碼為了解決上述問(wèn)題我們需要改代碼 但當(dāng)我們?cè)诩t杠狀態(tài)時(shí),我們不能寫(xiě)且但當(dāng)我們?cè)诩t杠狀態(tài)時(shí),我們不能寫(xiě)且他測(cè)試代碼他測(cè)試代碼 而沒(méi)有

51、測(cè)試代碼我們就不能修改新代碼而沒(méi)有測(cè)試代碼我們就不能修改新代碼 所以正確的做法是退回所以正確的做法是退回Money times(int multiplier) return new Franc(amount * multiplier, currency); 現(xiàn)在可以寫(xiě)測(cè)試了現(xiàn)在可以寫(xiě)測(cè)試了 判斷不同類(lèi)的幣種相同判斷不同類(lèi)的幣種相同public void testDifferentClassEquality() assertTrue(new Money(10, CHF).equals(new Franc(10, CHF); 修改修改Equals方法方法 從判斷類(lèi)到判斷幣種字符串,從判斷類(lèi)到判斷幣

52、種字符串, Moneypublic boolean equals(Object object) Money money = (Money)object;return amount = money.amount & currency().equals(money.currency(); 再次嘗試用再次嘗試用Money FrancMoney times(int multiplier) return new Money(amount * multiplier, currency); 成功,而且代碼一樣,合并到成功,而且代碼一樣,合并到Money DollarMoney times(int multi

53、plier) return new Money(amount * multiplier, currency);Money times(int multiplier) return new Money(amount * multiplier, currency); To-do list又想到一些,至少有完成的:$5+10CHF= $10 if rate is 2:1$5*2=$10amount應(yīng)該是私有的應(yīng)該是私有的Dollar side-effects貨幣取整equals()方法方法equal空值的支持equal對(duì)象5CHF*2=10CHF,F(xiàn)ranc side effectsDollar/F

54、ranc的冗余問(wèn)題方法方法equals通用化通用化方法方法times通用化通用化Dollar和和Franc的的equals問(wèn)題問(wèn)題引入幣種的概念(用最簡(jiǎn)單的字符串表示幣種)引入幣種的概念(用最簡(jiǎn)單的字符串表示幣種)去除重復(fù)的testFrancMultiplicaion案例 Chapter 11只有只有Money To-do list又想到一些,至少有完成的:$5+10CHF= $10 if rate is 2:1$5*2=$10amount應(yīng)該是私有的應(yīng)該是私有的Dollar side-effects貨幣取整equals()方法方法equal空值的支持equal對(duì)象5CHF*2=10CHF,F(xiàn)

55、ranc side effectsDollar/Franc的冗余問(wèn)題(只剩下構(gòu)造函數(shù)了)的冗余問(wèn)題(只剩下構(gòu)造函數(shù)了)方法方法equals通用化通用化方法方法times通用化通用化Dollar和和Franc的的equals問(wèn)題問(wèn)題引入幣種的概念(用最簡(jiǎn)單的字符串表示幣種)引入幣種的概念(用最簡(jiǎn)單的字符串表示幣種)去除重復(fù)的testFrancMultiplicaion案例 構(gòu)造函數(shù)構(gòu)造函數(shù) 嘗試替換對(duì)構(gòu)造函數(shù)的調(diào)用,嘗試替換對(duì)構(gòu)造函數(shù)的調(diào)用,Money 沒(méi)有對(duì)沒(méi)有對(duì)Dollar類(lèi)的調(diào)用了,可以直接刪掉類(lèi)的調(diào)用了,可以直接刪掉了了static Money dollar(int amount) re

56、turn new Money(amount, USD);static Money franc(int amount) return new Money(amount, CHF); 刪除刪除Franc 對(duì)對(duì)Franc類(lèi)還有一處引用類(lèi)還有一處引用 但是離開(kāi)但是離開(kāi)Franc類(lèi),這個(gè)測(cè)試就和另一個(gè)類(lèi),這個(gè)測(cè)試就和另一個(gè)測(cè)試等價(jià)了測(cè)試等價(jià)了public void testDifferentClassEquality() assertTrue(new Money(10, CHF).equals(new Franc(10, CHF);public void testEquality() assertTru

57、e(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); 刪除多余的測(cè)試刪除多余的測(cè)試 刪除對(duì)刪除對(duì)Franc類(lèi)還有一處引用的測(cè)試類(lèi)還有一處引用的測(cè)試 刪除等價(jià)測(cè)試刪除等價(jià)測(cè)試p

58、ublic 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.franc(

59、6);assertFalse(Money.franc(5).equals(Money.dollar(5); To-do list又想到一些,至少有完成的:$5+10CHF= $10 if rate is 2:1$5*2=$10amount應(yīng)該是私有的應(yīng)該是私有的Dollar side-effects貨幣取整equals()方法方法hashCodeequal空值的支持equal對(duì)象5CHF*2=10CHF,F(xiàn)ranc side effectsDollar/Franc的冗余問(wèn)題的冗余問(wèn)題方法方法equals通用化通用化方法方法times通用化通用化Dollar和和Franc的的equals問(wèn)題問(wèn)題

60、引入幣種的概念(用最簡(jiǎn)單的字符串表示幣種)引入幣種的概念(用最簡(jiǎn)單的字符串表示幣種)去除重復(fù)的testFrancMultiplicaion案例 Chapter 12加法加法 To-do list新的一天我們得到一個(gè)精簡(jiǎn)的to-do list: $5+10CHF= $10 if rate is 2:1 To-do list逐漸增加一些想法: $5+10CHF= $10 if rate is 2:1 $5+$5=$10 增加測(cè)試案例增加測(cè)試案例 簡(jiǎn)單的測(cè)試簡(jiǎn)單的測(cè)試public void testSimpleAddition() Money sum = Money.dollar(5).plus(M

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論