面向對象軟件開發的敏捷過程(二)
測試驅動示例,應用重構優化設計
下面通過一個簡單的測試驅動示例,并經過重構完成設計的更改。詳細的例子見重構。
影片出租店的程序,計算每一位顧客的消費金額并打印報表。操作者告訴程序:顧客租用了哪些影片,租期多長,程序根據租賃時間和影片類型(普通片,兒童片和新片)。除了計算費用,還要為常客計算點數,點數的計算會由于租片種類是否為新片而有所不同。
根據上述描述,我們畫出簡單的類圖
其中影片和租借都是簡單的純數據類。
package chapter01;
public class Movie {
?????? public static final int CHILDRENS=2;// 影片類型
?????? public static final int REGULAR=1;
?????? public static final int NEW_RELEASE=0;
??????
?????? private String title;// 名稱
?????? private int priceCode;// 價格代碼
?????? public Movie(String title, int priceCode) {
????????????? this.title = title;
????????????? this.priceCode = priceCode;
?????? }
?????? public int getPriceCode() {
????????????? return priceCode;
?????? }
?????? public void setPriceCode(int priceCode) {
????????????? this.priceCode = priceCode;
?????? }
?????? public String getTitle() {
????????????? return title;
?????? }
??????
?????? }
public class Rental {
?????? private Movie movie;
?????? private int dayRented;
?????? public Rental(Movie movie, int dayRented) {
?????????????
????????????? this.movie = movie;
????????????? this.dayRented = dayRented;
?????? }
?????? public int getDayRented() {
????????????? return dayRented;
?????? }
?????? public Movie getMovie() {
????????????? return movie;
?????? }
??????
}
public class Customer {
?????? private String name;
?????? private Vector rentals=new Vector();
?????? public Customer(String name) {
?????????????
????????????? this.name = name;
?????? }
?????? public String getName() {
????????????? return name;
?????? }
?????? public Vector getRentals() {
????????????? return rentals;
?????? }
?????? @SuppressWarnings("unchecked")
?????? public void addRental(Rental rental){
????????????? rentals.add(rental);
?????? }
?????? public String statement(){// 計算費用
????????????? double totalAmount=0;// 總和
????????????? int frequentCount=0;// 常客積點
????????????? Enumeration rental=rentals.elements();
????????????? String result="rental record for "+getName()+"\n";
????????????? while (rental.hasMoreElements()) {
???????????????????? Rental each = (Rental) rental.nextElement();// 取得一批租借記錄
???????????????????? double thisAmount=0;
???????????????????? // 根據類型,計算價格
???????????????????? switch (each.getMovie().getPriceCode()) {
???????????????????? case Movie.REGULAR:
??????????????????????????? thisAmount+=2;
??????????????????????????? if(each.getDayRented()>2)
?????????????????????????????????? thisAmount+=(each.getDayRented()-2)*1.5;
??????????????????????????? break;
???????????????????? case Movie.CHILDRENS:
??????????????????????????? thisAmount+=1.5;
??????????????????????????? if(each.getDayRented()>3)
?????????????????????????????????? thisAmount+=(each.getDayRented()-3)*1.5;
??????????????????????????? break;
???????????????????? case Movie.NEW_RELEASE:
??????????????????????????? thisAmount+=(each.getDayRented())*3;
??????????????????????????? break;
???????????????????? }
???????????????????? // 添加常客積點
???????????????????? frequentCount++;
???????????????????? if (each.getMovie().getPriceCode()==Movie.NEW_RELEASE&&each.getDayRented()>1)
??????????????????????????? frequentCount++;
???????????????????? // 顯示此筆數據
???????????????????? result+=
??????????????????????????? "\t"+each.getMovie().getTitle()+
??????????????????????????? "\t"+String.valueOf(frequentCount)+"\n";
????????????????????
???????????????????? totalAmount+=thisAmount;
????????????? }
????????????? // 打印結尾
????????????? result+="amount owned "+String.valueOf(totalAmount)+"\n";
????????????? result+="you earned "+String.valueOf(frequentCount)+"frequentCount\n";
?????????????
????????????? return result;
?????? }
}
下面是對應的測試用例
public class testCustomerStatement extends TestCase {
?????? Movie childrenMovie=new Movie("HARRY POTTY",Movie.CHILDRENS);
?????? Movie regularMovie=new Movie("Titanic",Movie.REGULAR);
?????? Movie newMovie=new Movie("Ice Age 2",Movie.NEW_RELEASE);
??????
?????? Rental childRental=new Rental(childrenMovie,3);
?????? Rental newRental=new Rental(newMovie,5);
?????? Rental regRental=new Rental(regularMovie,5);
??????
?????? Customer tom=new Customer("Tom");
??????
?????? protected void setUp() throws Exception {
????????????? super.setUp();
????????????? tom.addRental(childRental);
????????????? tom.addRental(newRental);
????????????? tom.addRental(regRental);
?????? }
??????
?????? public void testCaustomerName(){
?????? assertEquals("Tom",tom.getName());
??????
??????
?????? }
?????? public void testIteratorSize(){
?????????????
?????? assertEquals(3,tom.getRentals().size());??????
?????? }
?????? public void testIteratorName(){
????????????? Enumeration rentals=tom.getRentals().elements();
????????????? while (rentals.hasMoreElements()) {
???????????????????? Rental each = (Rental) rentals.nextElement();
???????????????????? switch(each.getMovie().getPriceCode()){
???????????????????? case Movie.CHILDRENS:
??????????????????????????? System.out.println("childrens");
??????????????????????????? assertEquals("HARRY POTTY",each.getMovie().getTitle());
??????????????????????????? assertEquals(3,each.getDayRented());
???????????????????????????
??????????????????????????? break;
???????????????????? case Movie.NEW_RELEASE:
??????????????????????????? System.out.println("new");
??????????????????????????? assertEquals("Ice Age 2",each.getMovie().getTitle());
??????????????????????????? assertEquals(5,each.getDayRented());
??????????????????????????? break;
???????????????????? case Movie.REGULAR:
??????????????????????????? System.out.println("regular");
??????????????????????????? assertEquals("Titanic",each.getMovie().getTitle());
??????????????????????????? assertEquals(5,each.getDayRented());
??????????????????????????? break;
???????????????????? }
???????????????????????????
????????????? }
?????? }
?????? public void testOutput(){
????????????? System.out.println(tom.statement());
?????? }
}
posted on 2006-08-15 17:09 amigojava 閱讀(1367) 評論(0) 編輯 收藏 所屬分類: 敏捷開發