当前位置:编程学习 > C#/ASP.NET >>

《重构》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# ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,