北國(guó)之春

          對(duì)象的歌唱

          常用鏈接

          統(tǒng)計(jì)

          我的豆瓣

          最新評(píng)論

          面向?qū)ο筌浖_(kāi)發(fā)的敏捷過(guò)程(三)

          ?

          編寫(xiě)的4個(gè)測(cè)試用例全部通過(guò)了,但是如果想對(duì)迭代器中每一個(gè)元素的計(jì)算結(jié)果進(jìn)行驗(yàn)證現(xiàn)有的函數(shù)就無(wú)法完成要求了。

          下面運(yùn)用重構(gòu)中的抽取函數(shù)分解Customer類(lèi)中超長(zhǎng)的方法statement(),這個(gè)函數(shù)完成的功能有些無(wú)所不包了。既計(jì)算各個(gè)租借的費(fèi)用和常客積點(diǎn),又要計(jì)算客戶需要交納的費(fèi)用總和,最后還要輸出報(bào)表的表頭和表尾。另外,現(xiàn)有的快速設(shè)計(jì)對(duì)變化的應(yīng)對(duì)不足,客戶的電影分類(lèi)可能會(huì)出現(xiàn)變化,如果去掉兒童片加上科幻片、故事片怎么辦,客戶的收費(fèi)規(guī)則發(fā)生變化了怎么辦。根據(jù)前面所說(shuō),他的味道不是一般的臭。

          第一步:抽取函數(shù)

          我們先把statement計(jì)算各個(gè)租借的費(fèi)用的職責(zé)分離到一個(gè)單獨(dú)的函數(shù)中。

          private double amountFor(Rental rental){

          ????????????? double thisAmount=0.0;

          ????????????? switch (rental.getMovie().getPriceCode()) {

          ????????????? case Movie.REGULAR:

          ???????????????????? thisAmount+=2;

          ???????????????????? if(rental.getDayRented()>2)

          ??????????????????????????? thisAmount+=(rental.getDayRented()-2)*1.5;

          ???????????????????? break;

          ????????????? case Movie.CHILDRENS:

          ???????????????????? thisAmount+=1.5;

          ???????????????????? if(rental.getDayRented()>3)

          ??????????????????????????? thisAmount+=(rental.getDayRented()-3)*1.5;

          ???????????????????? break;

          ????????????? case Movie.NEW_RELEASE:

          ???????????????????? thisAmount+=(rental.getDayRented())*3;

          ???????????????????? break;

          ????????????? }

          ????????????? return thisAmount;

          ?????????????

          ?????? }

          把原來(lái)的計(jì)算各個(gè)租借費(fèi)用的部分注釋起來(lái),把private double thisAmount=0.0; 一句改為double thisAmount=amountFor(each);再次運(yùn)行測(cè)試用例,和第一次的結(jié)果對(duì)比

          我們通過(guò)人工比對(duì)輸出結(jié)果,輸出結(jié)果相同。我們稍后會(huì)通過(guò)測(cè)試用例由套件自動(dòng)比對(duì)。

          如果這一步我們的測(cè)試fail掉了,由于我們只走了很小的一步,因此我們可以輕易的退回去。記住,我們始終保持測(cè)試-〉編碼(重構(gòu))-〉測(cè)試的步驟,小步快走的穩(wěn)定節(jié)奏。

          測(cè)試全部通過(guò)后,我們可以果斷的刪除剛才留在statement函數(shù)中我們注釋過(guò)的臨時(shí)代碼。

          分析我們剛剛抽取出來(lái)的amountFor函數(shù),它只使用了rental類(lèi)中的成員變量,放在Customer

          類(lèi)中并不合適,因此我們繼續(xù)重構(gòu),把amountfor函數(shù)移動(dòng)到Rental類(lèi)中。

          這里我們使用了集成開(kāi)發(fā)環(huán)境中的功能:


          這里我們看到eclipse自動(dòng)偵測(cè)出目標(biāo)的類(lèi)為rental,我們把新的函數(shù)改名為getcharge,并勾選在原類(lèi)型中創(chuàng)建委托,可以點(diǎn)擊預(yù)覽按鈕察看重構(gòu)結(jié)果,最后的結(jié)果如下:

          Rental 類(lèi)中:

          double getCharge(){

          ????????????? double thisAmount=0.0;

          ????????????? switch (getMovie().getPriceCode()) {

          ????????????? case Movie.REGULAR:

          ???????????????????? thisAmount+=2;

          ???????????????????? if(getDayRented()>2)

          ??????????????????????????? thisAmount+=(getDayRented()-2)*1.5;

          ???????????????????? break;

          ????????????? case Movie.CHILDRENS:

          ???????????????????? thisAmount+=1.5;

          ???????????????????? if(getDayRented()>3)

          ??????????????????????????? thisAmount+=(getDayRented()-3)*1.5;

          ???????????????????? break;

          ????????????? case Movie.NEW_RELEASE:

          ???????????????????? thisAmount+=(getDayRented())*3;

          ???????????????????? break;

          ????????????? }

          ????????????? return thisAmount;

          ?????????????

          ?????? }

          可以看到比amountfor函數(shù)更加簡(jiǎn)化。

          Customer類(lèi)中:

          private double amountFor(Rental rental){

          ????????????? return rental.getCharge();

          ?????? }

          保留了一個(gè)rental示例的委托調(diào)用。

          再次運(yùn)行測(cè)試用例,通過(guò)。

          我們繼續(xù)前進(jìn)!

          我們回到Customer類(lèi)中,察看Statement函數(shù)中的thisAmount變量,我們發(fā)現(xiàn)他的結(jié)果并沒(méi)有發(fā)生變化,我們可以通過(guò)重構(gòu)把這個(gè)無(wú)用的臨時(shí)變量除去。直接把thisamount=amountFor(each);的語(yǔ)句右側(cè)考到totalAmount+=thisAmount;語(yǔ)句右側(cè),編譯器會(huì)提示thisamount變量并未使用,直接雙擊quick fix 除去這個(gè)變量。再次運(yùn)行測(cè)試用例,通過(guò)。

          下一步我們把計(jì)算常客積點(diǎn)的職責(zé)也從statement函數(shù)中分離出來(lái):

          我們添加函數(shù)

          private int getFrequentCount(Rental rental){

          ?????????????

          ????????????? if (rental.getMovie().getPriceCode()==Movie.NEW_RELEASE&&rental.getDayRented()>1)

          ???????????????????? return 2;

          ????????????? else return 1;

          ?????? }

          再把計(jì)算常客積點(diǎn)的部分改寫(xiě)如下:

          ???????????????????? frequentCount+=getFrequentCount(each);

          測(cè)試后我們發(fā)現(xiàn)常客積點(diǎn)的計(jì)算和類(lèi)Rental的關(guān)系更密切,我們?cè)俅我苿?dòng)getFrequentCountrental類(lèi)中。測(cè)試通過(guò)后,計(jì)算常客積點(diǎn)的部分改寫(xiě)如下:

          ???????????????????? frequentCount+= each.getFrequentCount();

          接下來(lái),我們把statement最后的兩個(gè)臨時(shí)變量frequentCounttotalAmount也通過(guò)替換為函數(shù)查詢(xún)消除掉。

          添加函數(shù)

          private double getTotalCharge(){

          ????????????? double result=0.0;

          ????????????? Enumeration rental=rentals.elements();

          ????????????? while (rental.hasMoreElements()) {

          ???????????????????? Rental rent = (Rental) rental.nextElement();

          ???????????????????? result+=rent.getCharge();

          ????????????? }

          ????????????? return result;

          ?????? }

          把臨時(shí)變量totalAmount替換為getTotalCharge()

          添加函數(shù)

          private int getTotalFrequentCount(){

          ????????????? int result=0;

          ????????????? Enumeration rental=rentals.elements();

          ????????????? while (rental.hasMoreElements()) {

          ???????????????????? Rental each = (Rental) rental.nextElement();

          ???????????????????? result+=each.getFrequentCount();

          ????????????? }

          ????????????? return result;

          ?????? }

          把臨時(shí)變量frequentCount替換為getTotalFrequentCount

          相應(yīng)的,我們?cè)跍y(cè)試中添加以下四條測(cè)試用例:

          public void testGetCharge(){

          ????????????? Enumeration rentals=tom.getRentals().elements();

          ????????????? while (rentals.hasMoreElements()) {

          ???????????????????? Rental each = (Rental) rentals.nextElement();

          ???????????????????? switch(each.getMovie().getPriceCode()){

          ???????????????????? case Movie.CHILDRENS:

          ??????????????????????????? assertEquals(1.5,each.getCharge(),.1);

          ???????????????????????????

          ??????????????????????????? break;

          ???????????????????? case Movie.NEW_RELEASE:

          ??????????????????????????? assertEquals(15,each.getCharge(),.1);

          ??????????????????????????? break;

          ???????????????????? case Movie.REGULAR:

          ??????????????????????????? assertEquals(6.5,each.getCharge(),.1);

          ??????????????????????????? break;

          ???????????????????? }

          ?????? }

          ?????? }

          ????????????? public void testgetFrequentCount(){

          ???????????????????? Enumeration rentals=tom.getRentals().elements();

          ???????????????????? while (rentals.hasMoreElements()) {

          ??????????????????????????? Rental each = (Rental) rentals.nextElement();

          ??????????????????????????? switch(each.getMovie().getPriceCode()){

          ??????????????????????????? case Movie.CHILDRENS:

          ?????????????????????????????????? assertEquals(1,each.getFrequentCount(),.1);

          ??????????????????????????????????

          ?????????????????????????????????? break;

          ??????????????????????????? case Movie.NEW_RELEASE:

          ?????????????????????????????????? assertEquals(2,each.getFrequentCount(),.1);

          ?????????????????????????????????? break;

          ??????????????????????????? case Movie.REGULAR:

          ?????????????????????????????????? assertEquals(1,each.getFrequentCount(),.1);

          ?????????????????????????????????? break;

          ??????????????????????????? }

          ????????????? }

          ?????? }

          ????????????? public void testGetTotalCharge(){

          ???????????????????? assertEquals(23,tom.getTotalCharge(),.1);

          ????????????? }

          ????????????? public void testGetTotalFrequentCount(){

          ???????????????????? assertEquals(4,tom.getTotalFrequentCount(),.1);

          ????????????? }

          現(xiàn)在我們就可以對(duì)迭代器中的每個(gè)元素的結(jié)果進(jìn)行驗(yàn)證了。

          posted on 2006-08-18 16:33 amigojava 閱讀(279) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 江陵县| 达拉特旗| 施秉县| 任丘市| 边坝县| 金乡县| 凤凰县| 兴安盟| 来凤县| 壤塘县| 新郑市| 蕲春县| 景泰县| 定安县| 平南县| 佛坪县| 永登县| 天水市| 绥宁县| 泽州县| 志丹县| 宁明县| 尚志市| 长宁区| 河西区| 南充市| 桐庐县| 元江| 綦江县| 伊春市| 弥渡县| 驻马店市| 宝山区| 建水县| 武川县| 丰城市| 金堂县| 武胜县| 阿拉尔市| 庆安县| 登封市|