《重构》C#版实现(二)抽取AmountFor方法
在开始前的最后一刻,还需要提醒的是,也许你带着满腔热情,想把代码重构得优雅极致,但就像平时的工作一样,重构的过程更需要的是理性思考,而不是冲动。每一次重构实践,都应该包含了对设计、实现、可维护、可扩展性,以及成本的估算和权衡。
所以,首先看看对于Statement方法来说,从哪里入手比较合适?
[csharp]
public string Statement()
{
double totalAmount = 0;
int frequentRenterPoints = 0;
string result = "Rental Record for " + Name + "\n";
foreach (Rental rental in Rentals)
{
double thisAmount = 0;
// determine amounts for each line
switch (rental.Movie.PriceCode)
{
case Movie.REGULAR:
thisAmount += 2;
if (rental.DaysRented > 2)
thisAmount += (rental.DaysRented - 2) * 1.5;
break;
case Movie.NEW_RELEASE:
thisAmount += rental.DaysRented * 3;
break;
case Movie.CHILDRENS:
thisAmount += 1.5;
if (rental.DaysRented > 3)
thisAmount += (rental.DaysRented - 3) * 1.5;
break;
}
// add frequent renter points
frequentRenterPoints++;
// add bonus for a two day new release rental
if (rental.Movie.PriceCode == Movie.NEW_RELEASE &&
rental.DaysRented > 1) frequentRenterPoints++;
// show figures for this rental
result += "\t" + rental.Movie.Title + "\t" + thisAmount.ToString() + "\n";
totalAmount += thisAmount;
}
// add footer lines
result += "Amount owed is " + totalAmount.ToString() + "\n";
result += "You earned " + frequentRenterPoints.ToString() + " frequent renter points";
return result;
}
实际上,应该换一个问题:对现在的程序来说,哪里最容易产生变化?毕竟,如果代码不会变化,重构就是多余的行为。优雅的代码只能满足程序员的审美需求,而不是客户对于功能的需求。
《重构》中指出:该程序最可能产生的变化有三点:
1.报告输出的类型可能变化,例如由普通字符串变成HTML格式的文本
2.计费方式可能发生变化
3.影片类型可能发生变化
无论哪一种变化,上面的Statement方法都不能很好地应对——它太胖了,涉及的逻辑、细节太多。所以,第一步,《重构》的作者选择将该方法中最长、并且同时涉及上述所有变化的,计算每一部影片花费的那个switch给抽取出去。
具体步骤是:
1.在Customer中新建一个计算花费的新方法AmountFor:
[csharp]
public int AmountFor(Rental rental)
{
return 0;
}
2.把switch的代码copy(不是剪切)到AmountFor里:
[csharp]
public int AmountFor(Rental rental)
{
switch (rental.Movie.PriceCode)
{
case Movie.REGULAR:
thisAmount += 2;
if (rental.DaysRented > 2)
thisAmount += (rental.DaysRented - 2) * 1.5;
break;
case Movie.NEW_RELEASE:
thisAmount += rental.DaysRented * 3;
break;
case Movie.CHILDRENS:
thisAmount += 1.5;
if (rental.DaysRented > 3)
thisAmount += (rental.DaysRented - 3) * 1.5;
break;
}
return 0;
}
3.但此时的代码是编译不了得,因为AmountFor中,thisAmount不存在。所以,在switch前面添加一个thisAmount的声明:
[csharp]
public int AmountFor(Rental rental)
{
int thisAmount = 0;
switch (rental.Movie.PriceCode)
{
case Movie.REGULAR:
thisAmount += 2;
if (rental.DaysRented > 2)
thisAmount += (rental.DaysRented - 2) * 1.5;
break;
case Movie.NEW_RELEASE:
thisAmount += rental.DaysRented * 3;
break;
case Movie.CHILDRENS:
thisAmount += 1.5;
if (rental.DaysRented > 3)
thisAmount
补充:软件开发 , C# ,