class Customer


1 import java.util.*;
2 
3 public class Customer {
4     private String _name;
5     private ArrayList _rentals = new ArrayList();
6 
7     public Customer(String name) {
8 	_name = name;
9     }
10 
11     public void addRental(Rental arg) {
12 	_rentals.add(arg);
13     }
14 
15     public String getName() {
16 	return _name;
17     }
18 
19     public String statement() 
20     {         
21 	double totalAmount = 0;         
22 	int frequentRenterPoints = 0;         
23 	Iterator rentals = _rentals.iterator();     
24 	String result = "Rental Record for " + getName() + "\n";
25 	while (rentals.hasNext ()) {
26 	    double thisAmount = 0;   
27 	    Rental each = (Rental) rentals.next();
28 	    //determine amounts for each line 
29 	    // Factor out that ugly switch statement into its own method
30 	    double anAmount = amountFor(each);
31 	    thisAmount = amountFor(each); 
32 	    // add frequent renter points 
33 	    frequentRenterPoints ++; // add bonus for a two day new release rental 
34 	    if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) 
35 		&&     each.getDaysRented() > 1)
36 		frequentRenterPoints ++; 
37 	    //show figures for this rental 
38 	    result += "\t" + each.getMovie().getTitle()+ "\t" +     
39 		thisAmount +
40 		"\n"; 
41 	    totalAmount += thisAmount; 
42 	}
43 	//add footer lines 
44 	result += "Amount owed is " + String.valueOf(totalAmount) + "\n"; 
45 
46 	result += "You earned " + String.valueOf(frequentRenterPoints) +
47 	    " frequent renter points"; 
48 	return result; 
49     }
50 
51     private int amountFor(Rental aRental) { //bug introduced
52 	int result = 0;
53 	switch (aRental.getMovie().getPriceCode()) {
54 	case Movie.REGULAR:         
55 	    result += 2;         
56 	    if (aRental.getDaysRented() > 2)
57 		result += (aRental.getDaysRented() - 2) * 1.5;
58 	    break;     
59 	case Movie.NEW_RELEASE:    
60 	    result += aRental.getDaysRented() * 3;     
61 	    break;     
62 	case Movie.CHILDRENS: 
63 	    result += 1.5;  
64 	    if (aRental.getDaysRented() > 3)   
65 		result += (aRental.getDaysRented() - 3) * 1.5;   
66 	    break; 
67 	}
68 	return result;
69     }
70 
71     public static void main(String argv[])
72     {
73 	Customer harry = new Customer("Harry");
74 	Movie movie = new Movie("Gone With The Wind", Movie.REGULAR);
75 	Rental rental = new Rental(movie, 3);
76 	harry.addRental(rental);
77 	System.out.println(harry.statement());
78     }
79 }
80 // Output:
81 // $ java -classpath . Customer
82 // Rental Record for Harry
83 //        Gone With The Wind      3.0
84 // Amount owed is 3.0
85 // You earned 1 frequent renter points
86 
87 // WHOA!  Our output has changed!
88 //  Just from moving the switch statement? 
89 //  Diagnosis:  thisAmount was declared as returning int
90 //             Should be double.
91 //  Remedy:  change return type to double, and change type of local
92 //           variable thisAmount to double as well.
93 //  Lesson:  refactor in small steps, test after each step
94 //           Finding bugs will be much simpler.
95 //  Note that amountFor uses only information from Rental--it should
96 //  be moved to Rental in next refactoring.