《重构》C#版实现(四)switch的多态化处理
首先,列出到现在为止,Movie类和Rental类的代码如下:
[csharp]
public class Movie
{
public const int CHILDRENS = 2;
public const int REGULAR = 0;
public const int NEW_RELEASE = 1;
public string Title { get; private set; }
public int PriceCode { get; private set; }
public Movie(string title, int priceCode)
{
Title = title;
PriceCode = priceCode;
}
}
public class Rental
{
public Movie Movie { get; private set; }
public int DaysRented { get; private set; }
public double Charge
{
get
{
double result = 0;
switch (Movie.PriceCode)
{
case Movie.REGULAR:
result += 2;
if (DaysRented > 2)
result += (DaysRented - 2) * 1.5;
break;
case Movie.NEW_RELEASE:
result += DaysRented * 3;
break;
case Movie.CHILDRENS:
result += 1.5;
if (DaysRented > 3)
result += (DaysRented - 3) * 1.5;
break;
}
return result;
}
}
public int FrequentRenterPoints
{
get
{
if (Movie.PriceCode == Movie.NEW_RELEASE && DaysRented > 1)
{
return 2;
}
else
{
return 1;
}
}
}
public Rental(Movie rented, int days)
{
Movie = rented;
DaysRented = days;
}
}
一、为价格计算寻找更合适的“家”
《重构》中提到一个考虑:该程序的一个主要变化点在于:影片类型很可能增加或发生变化。而目前来说,跟影片类型先关的代码分散在上面两个类中。在另一本书《代码整洁之道》中,提到一个原则:如果某些代码的修改频度一致,则应该把它们尽可能放在一起。放在我们这儿,意味着,如果我们在Movie类中增加了影片类型,意味着也要去修改Rental类的Charge属性,这种修改涉及到了两个类。假设情景是在大得多的项目中,则有可能是要修改两个不同的文件,甚至是不同的项目或程序集。而后面的这些情景通常会产生大量的BUG。而如果将修改频度一致的内容放在一起(同一个文件,甚至是同一个类中),则内容的同步也会变得更容易,BUG产生的几率会更低。
综上所述,我们需要把Rental关于Charge的计算过程迁移到Movie类中——虽然会带来多一层间接性,以换取程序的高可维护、可扩展性:
1.在Movie类中创建一个ChargeFor方法,并将Rental.Charge属性的代码抄过去:
[csharp]
public double ChargeFor(int daysRented)
{
double result = 0;
switch (PriceCode)
{
case Movie.REGULAR:
result += 2;
if (daysRented > 2)
result += (daysRented - 2) * 1.5;
break;
case Movie.NEW_RELEASE:
result += daysRented * 3;
break;
case Movie.CHILDRENS:
result += 1.5;
if (daysRented > 3)
result += (daysRented - 3) * 1.5;
break;
}
return result;
}
注意,在代码迁移时,可能存在一些问题,诸如原本PriceCode是使用Rental的Movie对象来调用的,而现在因为它成为了自身的属性,所以也就没有必要使用Movie对象了。
2.修改Rental.Charge属性,让它通过委托给Movie的新方法来完成计算:
[csharp]
public double Charge
{
get
{
return Movie.ChargeFor(DaysRented);
}&
补充:软件开发 , C# ,