1.4重构-第一章

         接1.3,本章对“常客积分计算”做类似处理。积分的计算视影片种类而有不同,不过不像收费规则有那么多变话。看来有理由把积分计算责任放在Rental类身上,首先需要针对“常客积分计算”这部分代码运用Extract Method(提炼函数)。

         再来看局部变量。这里再一次用到了each,而它可以被当作参数传入新函数中。另一个临时变量是frequentRenterPoints。本例中,它在使用之前已经有初始值了,但是提炼出来的函数并没有读取该值,所以我们不需要将它当作参数传递进去,只需把新函数的返回值累加上去就可行了。

重构前的代码

public String statement(){
	double totalAmount = 0;//总金额
	int frequentRenterPoints = 0;//本次总积分
	
	Enumeration<Rental> rentals = _rentals.elements();
	// 租赁备案
	String result = "Rental Record for "+getName()+"\n";
	while(rentals.hasMoreElements()){
		Rental each = rentals.nextElement();
		
		// 常规积分累加
		frequentRenterPoints++;
		// 特殊新书积分计算
		if (each.get_movie().get_priceCode() == Movie.NEW_RELEASE &&
			each.get_dayRented() > 1) {
			frequentRenterPoints++;
		}
		
		// 显示凭条
		result += "\t"+each.get_movie().get_title()+"\t"+String.valueOf(each.getCharge())+"\n";
		totalAmount += each.getCharge();
	}
	
	// 组装页脚
	result += "Amount owed is "+String.valueOf(totalAmount)+"\n";
	result += "You earned "+String.valueOf(frequentRenterPoints)+" frequent renter points";
	return result;
}
重构后的代码
class Customer...
public String statement(){
	double totalAmount = 0;//总金额
	int frequentRenterPoints = 0;//本次总积分
	
	Enumeration<Rental> rentals = _rentals.elements();
	// 租赁备案
	String result = "Rental Record for "+getName()+"\n";
	while(rentals.hasMoreElements()){
		Rental each = rentals.nextElement();
		frequentRenterPoints += each.getFrequentRenterPoints();
		
		// 显示凭条
		result += "\t"+each.get_movie().get_title()+"\t"+String.valueOf(each.getCharge())+"\n";
		totalAmount += each.getCharge();
	}
	
	// 组装页脚
	result += "Amount owed is "+String.valueOf(totalAmount)+"\n";
	result += "You earned "+String.valueOf(frequentRenterPoints)+" frequent renter points";
	return result;
}
class Rental...
// 常客积分计算
public int getFrequentRenterPoints(){
	if (get_movie().get_priceCode() == Movie.NEW_RELEASE &&
		get_dayRented() > 1) {
		return 2;
	}else{
		return 1;
	}
}
最终的UML:


去除临时变量

         正如我们之前说的那样,临时变量可能是个问题。它们只在自己所属的函数中有效,所以它们会助长冗长而复杂的函数。这里有两个临时变量,两者都是用来从Customer对象相关中的Rental对象中获取某个总量。不论哪个版本的都需要这些总量。我打算运用Replace Temp with Query(以查询代替临时变量),并利用查询函数(querymethod)来取代totalAmount和frequentRentalPoints这两个临时变量。由于类中的任何函数都可以调用上述查询函数,所以它能促成较干净的设计,而减少冗长复杂的函数。

         首先用Customer类的getTotalCharge()取代totalAmount,由于totalAmount在循环内部被赋值,所以不得不把循环复制到查询函数中。

class Customer...
public String statement(){
	int frequentRenterPoints = 0;//本次总积分
	
	Enumeration<Rental> rentals = _rentals.elements();
	// 租赁备案
	String result = "Rental Record for "+getName()+"\n";
	while(rentals.hasMoreElements()){
		Rental each = rentals.nextElement();
		frequentRenterPoints += each.getFrequentRenterPoints();
		
		// 显示凭条
		result += "\t"+each.get_movie().get_title()+"\t"+String.valueOf(each.getCharge())+"\n";
	}
	
	// 组装页脚
	result += "Amount owed is "+String.valueOf(getTotalCharge())+"\n";
	result += "You earned "+String.valueOf(frequentRenterPoints)+" frequent renter points";
	return result;
}

// 计算总金额
public double getTotalCharge(){
	double result = 0;
	Enumeration<Rental> rentals = _rentals.elements();
	while(rentals.hasMoreElements()){
		Rental each = rentals.nextElement();
		result += each.getCharge();
	}
	return result;
}

         重构后,重新编译并测试,然后以同样的手法处理frequentRentalPints。

class Customer...
public String statement(){
	Enumeration<Rental> rentals = _rentals.elements();
	// 租赁备案
	String result = "Rental Record for "+getName()+"\n";
	while(rentals.hasMoreElements()){
		Rental each = rentals.nextElement();
		
		// 显示凭条
		result += "\t"+each.get_movie().get_title()+"\t"+String.valueOf(each.getCharge())+"\n";
	}
	
	// 组装页脚
	result += "Amount owed is "+String.valueOf(getTotalCharge())+"\n";
	result += "You earned "+String.valueOf(getTotalFrequentRenterPoints())+" frequent renter points";
	return result;
}

//计算总积分
public int getTotalFrequentRenterPoints(){
	int result = 0;
	Enumeration<Rental> rentals = _rentals.elements();
	while(rentals.hasMoreElements()){
		Rental each = rentals.nextElement();
		result += each.getFrequentRenterPoints();
	}
	return result;
}
 重新编译并测试

最终的UML

 




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值