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

《重构》C#版实现(三)Statement的整体重构

一、重命名AmountFor的局部变量
首先看看我们先前抽取出来的AmountFor方法:
[csharp] view plaincopy
public double AmountFor(Rental rental) 

    double 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 += (rental.DaysRented - 3) * 1.5; 
            break; 
    } 
    return thisAmount; 

方法中有个局部变量:thisAmount,实际上,该名称是在Statement方法中起的。而对于AmountFor方法而言,只可能有一个amount,对应传参进来的rental。所以,加上this的修饰反而是画蛇添足的做法。而我也不太认同《重构》中对该局部变量的新命名(result),result一词过于宽泛,也有许多其它数据提到过这个问题,例如避免使用如result,item,manager,这一类“万能”词汇。所以,改进后的代码如下:
[csharp] view plaincopy
private double AmountFor(Rental rental) 

    double amount = 0; 
    switch (rental.Movie.PriceCode) 
    { 
        case Movie.REGULAR: 
            amount += 2; 
            if (rental.DaysRented > 2) 
                amount += (rental.DaysRented - 2) * 1.5; 
            break; 
        case Movie.NEW_RELEASE: 
            amount += rental.DaysRented * 3; 
            break; 
        case Movie.CHILDRENS: 
            amount += 1.5; 
            if (rental.DaysRented > 3) 
                amount += (rental.DaysRented - 3) * 1.5; 
            break; 
    }  
     
    return amount; 

如书上所言,不要忽视这种微小的重构,它的确能降低代码的理解难度。试想,如果一个朋友本想和你说“圣诞快乐”,却说成了“新年幸福”,这也许在易做图国家并不存在太大问题,但是中国人却是难以将两件事情联系在一起的。所以,让你的命名确切地表示它的意思,这很重要。在我的编码工作中,甚至可能超过15%的时间是花在为类、方法、字段等内容的命名上,浪费吗?一点都不!
二、将AmountFor方法转移到Rental类
《重构》:目前的AmountFor没有使用任何Customer类的属性、字段、方法,它在不在Customer方法中其实并不是那么重要,而这正是暗示该方法不应该属于该类型的明确信号,Rental类才是它的归属地。下面是重构的过程:
1.在Rental类中创建一个Charge属性,并将AmountFor中的代码抄过去:
[csharp] 
public double Charge 

    get 
    { 
        double amount = 0; 
        switch (Movie.PriceCode) 
        { 
            case Movie.REGULAR: 
                amount += 2; 
                if (DaysRented > 2) 
                    amount += (DaysRented - 2) * 1.5; 
                break; 
            case Movie.NEW_RELEASE: 
                amount += DaysRented * 3; 
                break; 
            case Movie.CHILDRENS: 
                amount += 1.5; 
                if (DaysRented > 3) 
                    amount += (DaysRented - 3) * 1.5; 
                break; 
        } 
 
 
        return amount; 
    } 

2.把原Customer的AmountFor方法体清空,但仍保留声明和空的函数体。
[csharp] 
private double AmountFor(Rental rental) 

    return 0; 

3.更改Customer的AmountFor实现为:
[csharp] 
private double AmountFor(Rental rental) 

    return rental.Charge; 

4.运行测试项目,如果不通过,则检查、修改代码。直到通过为止
5.修改Statement方法,使其不调用自身类的AmountFor方法来取得Rental的Amount,而是直接问Rental要:
[csharp] 
public string Statement() 

    double totalAmount = 0; 
    int frequentRenterPoints = 0; 
    string result = "Rental Record for " + Name + "\n"; 
    foreach (Rental rental in Rentals) 
    { 
        double thisAmount = rental.Charge; 
 
        // add frequent renter points 
        frequentRenterPoints++; 
        // add bonus for a two day new release rental 
        if (rental.Movie.Pric

补充:软件开发 , C# ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,