实例代码:
public String statement() {
double totalAmount = 0;
int frequentRenterPoints = 0;
Enumeration rentals = _rentals.elements();
String result = "Rental Record for * " + getName() + "\n";
while(rentals.hasMoreElements()) {
double thisAmount = 0;
Rental each = (Rental)rentals.nextElement(); //取得一笔租借记录
switch(each.getMovie().getPriceCode()) { //取得影片出租价格
case Movie.REGULAR: //普通片
thisAmount += 2;
if(each.getDaysRented() > 2)
thisAmount += (each.getDaysRented() - 2) * 1.5;
break;
case Movie.NEW_RELEASE: //新片
thisAmount += each.getDaysRented() * 3;
break;
case Movie.CHILDRENS: //儿童片
thisAmount += 1.5;
if(each.getDaysRented() > 3)
thisAmount += (each.getDaysRented() - 3) * 1.5;
break;
}
// add frequent renter points(累加常客积点)
frequentRenterPoints ++;
if((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) &&
each.getDaysRented() > 1)
frequentRenterPoints ++;
result += "\t" + each.getMovie().getTitle() + "\t" +
String.valueOf(thisAmount) + "\n";
totalAmount += thisAmount;
}
// add footer lines(结尾打印)
result += "Amount owed is " + String.valueOf(totalAmount) + " \n";
result += "You earned " + String.valueOf(frequentRenterPoints) +
"frequent renter points";
return result;
}
第一步骤是找出代码的逻辑泥团并运用Extract Method(110).本例一个明显的逻辑泥团就是switch语句,把它提炼(extract)到独立函数中似乎比较好.
首先我得在这段代码里头找出函数内的局部变量(local
variables)和参数(parameters).我找到了两个:each和thisAmount,前者并未被修改,后者会被修改.任何不会被修改的
变量都可以被我当成参数传入新的函数,至于会被修改的变量就需格外小心.如果只有一个变量会被修改,我可以把它当作返回值.thisAmount是个临时
变量,其值在每次循环起始处被设为0,并且在switch语句之前不会改变,所以我可以把新函数的返回值赋予它.
public String statement() {
double totalAmount = 0;
int frequentRenterPoints = 0;
Enumeration rentals = _rentals.elements();
String result = "Rental Record for * " + getName() + "\n";
while(rentals.hasMoreElements()) {
double thisAmount = 0;
Rental each = (Rental)rentals.nextElement(); //取得一笔租借记录
thisAmount = amountFor(each);
// add frequent renter points(累加常客积点)
frequentRenterPoints ++;
if((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) &&
each.getDaysRented() > 1)
frequentRenterPoints ++;
result += "\t" + each.getMovie().getTitle() + "\t" +
String.valueOf(thisAmount) + "\n";
totalAmount += thisAmount;
}
// add footer lines(结尾打印)
result += "Amount owed is " + String.valueOf(totalAmount) + " \n";
result += "You earned " + String.valueOf(frequentRenterPoints) +
"frequent renter points";
return result;
}
public double amountFor(Rental each) {
double thisAmount = 0;
switch(each.getMovie().getPriceCode()) { //取得影片出租价格
case Movie.REGULAR: //普通片
thisAmount += 2;
if(each.getDaysRented() > 2)
thisAmount += (each.getDaysRented() - 2) * 1.5;
break;
case Movie.NEW_RELEASE: //新片
thisAmount += each.getDaysRented() * 3;
break;
case Movie.CHILDRENS: //儿童片
thisAmount += 1.5;
if(each.getDaysRented() > 3)
thisAmount += (each.getDaysRented() - 3) * 1.5;
break;
}
return thisAmount;
}
现在,已经把原本的函数分为两块,可以分别处理它们.我不喜欢amountFor()内的某些变量名称,现在是修改它们的时候.
下面是原本的代码:
public double amountFor(Rental each) {
double thisAmount = 0;
switch(each.getMovie().getPriceCode()) { //取得影片出租价格
case Movie.REGULAR: //普通片
thisAmount += 2;
if(each.getDaysRented() > 2)
thisAmount += (each.getDaysRented() - 2) * 1.5;
break;
case Movie.NEW_RELEASE: //新片
thisAmount += each.getDaysRented() * 3;
break;
case Movie.CHILDRENS: //儿童片
thisAmount += 1.5;
if(each.getDaysRented() > 3)
thisAmount += (each.getDaysRented() - 3) * 1.5;
break;
}
return thisAmount;
}
下面是易名后的代码:
public double amountFor(Rental aRental) {
double result = 0;
switch(aRental.getMovie().getPriceCode()) { //取得影片出租价格
case Movie.REGULAR: //普通片
result += 2;
if(aRental.getDaysRented() > 2)
result += (aRental.getDaysRented() - 2) * 1.5;
break;
case Movie.NEW_RELEASE: //新片
result += aRental.getDaysRented() * 3;
break;
case Movie.CHILDRENS: //儿童片
result += 1.5;
if(aRental.getDaysRented() > 3)
result += (aRental.getDaysRented() - 3) * 1.5;
break;
}
return result;
}