北國之春

          對象的歌唱

          常用鏈接

          統(tǒng)計

          我的豆瓣

          最新評論

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

          ?

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

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

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

          我們先把statement計算各個租借的費用的職責(zé)分離到一個單獨的函數(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;

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

          ?????? }

          把原來的計算各個租借費用的部分注釋起來,把private double thisAmount=0.0; 一句改為double thisAmount=amountFor(each);再次運行測試用例,和第一次的結(jié)果對比

          我們通過人工比對輸出結(jié)果,輸出結(jié)果相同。我們稍后會通過測試用例由套件自動比對。

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

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

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

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

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


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

          Rental 類中:

          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ù)更加簡化。

          Customer類中:

          private double amountFor(Rental rental){

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

          ?????? }

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

          再次運行測試用例,通過。

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

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

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

          我們添加函數(shù)

          private int getFrequentCount(Rental rental){

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

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

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

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

          ?????? }

          再把計算常客積點的部分改寫如下:

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

          測試后我們發(fā)現(xiàn)常客積點的計算和類Rental的關(guān)系更密切,我們再次移動getFrequentCountrental類中。測試通過后,計算常客積點的部分改寫如下:

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

          接下來,我們把statement最后的兩個臨時變量frequentCounttotalAmount也通過替換為函數(shù)查詢消除掉。

          添加函數(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;

          ?????? }

          把臨時變量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;

          ?????? }

          把臨時變量frequentCount替換為getTotalFrequentCount

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

          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)在我們就可以對迭代器中的每個元素的結(jié)果進(jìn)行驗證了。

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


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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 宁明县| 南丰县| 梅河口市| 沙雅县| 布拖县| 西和县| 蒙城县| 兴文县| 白沙| 郁南县| 腾冲县| 乌兰县| 积石山| 汽车| 安吉县| 闽清县| 扶余县| 武乡县| 延川县| 石阡县| 四平市| 邢台市| 平塘县| 铜鼓县| 广灵县| 巴中市| 兰考县| 东乡| 名山县| 辽宁省| 谷城县| 竹北市| 徐汇区| 凤凰县| 丰原市| 广宗县| 巴林右旗| 铁力市| 双鸭山市| 那坡县| 深圳市|