Replace Parameter with Methods (以函數取代參數)

Summary 對象調用某個函數,並將所得結果做爲參數,傳遞給另外一個函數。而接受該纔是的函數自己也可以調用前一個函數。讓參數接受者去除該項參數,並直接調用前一個函數java

動機:函數

  若是函數能夠經過其餘途徑得到參數值,那麼它就不該該經過參數取得該值。過長的參數列會增長程序閱讀者的理解難度,所以咱們應該儘量縮短參數列的長度。測試

縮減參數列的辦法之一就是:看看參數接受端是否能夠經過與調用端相同的計算來取得參數值。若是調用端經過其所屬對象內部的另外一個函數來計算參數,並在計算過程當中不曾引用調用端的其餘參數,那麼你就應該能夠將這個計算過程轉移到被調用端內,從而去除該項參數。若是你所調用的函數隸屬於另外一對象,而該對象擁有調用端所屬對象的引用,前面所說的這些也一樣適用。spa

可是,若是參數值的計算過程依賴於調用端的某個參數,那麼你就沒法去掉被調用端的參數,由於每一次調用動做中,該參數值均可能不一樣(固然,若是你可以運用Replace Parameter with Explicit Methods將該參數替換爲一個函數,又另當別論)。另外若是參數接受端並無參數發送端對象的引用,而你也不想加上這樣一個引用,那麼也沒法去除參數。code

有時候,參數的存在是爲了未來的靈活性。這種狀況下咱們仍然須要把這種多餘參數拿掉。是的,你應該只在必要關頭才添加參數,預先添加的參數極可能並非你所須要的。不過,對於這條規則,也有一個例外:若是修改接口會對整個程序形成很是痛苦的結果(例如須要很長時間來從新構建程序,或須要修改大量代碼),那麼能夠考慮保留前人預先加入的參數。若是真是這樣,你應該首先判斷修改接口究竟會形成多嚴重的後果,而後考慮是否應該下降系統各部位之間的依賴,以減小修改接口所形成的影響。穩定的接口確實很好,可是被凍結在一個不良接口上也是有問題的。對象

作法:接口

1. 若是有必要,將參數的計算過程提煉到一個獨立函數中。ci

2. 將函數本體內引用該參數的地方改成調用新建的函數。get

3.每次替換後,修改並測試。it

4.所有替換完成後,使用Remove Parameter將該參數去掉。

     範例:

    如下代碼用於計算訂單折扣價格。雖然這麼低的折扣不打可能出如今現實生活中,不過做爲一個範例,咱們暫不考慮着一點:

public double getPrice(){
    int basePrice = _quantity * _itemPrice;
    int discountLevel;
    if(_quantity > 100){
        discountLevel = 2;
    }else{
        discountLevel = 1;
    }
    double final Price = discountedPrice(basePrice, discountLevel);
    return finalPrice;
}

private double discountedPrice(int basePrice, int discountLevel){
    if(discountLevel == 2){
        return basePrice * 0.1;
    }else{
        return basePrice * 0.05;
    }
}

首先,咱們把計算折扣等級(discountLevel)的代碼提煉成爲一個獨立的getDiscountLevel()函數:

public double getPrice(){
    int basePrice = _quantity * _itemPrice;
    int discountLevel = getDiscountLevel();
    double final Price = discountedPrice(basePrice, discountLevel);
    return finalPrice;
}

private int getDiscountLevle(){
    if(_quantity > 100){
            return 2;
     }else{
            return 1;
     }
}

而後把discountedPrice()函數中對discountLevel參數的全部引用點,替換爲對getDiscountLevel()函數的調用:

private double discountedPrice(int basePrice, int discountLevel){
    if(getDiscountLevle() == 2){
        return basePrice * 0.1;
    }else{
        return basePrice * 0.05;
    }
}

此時,咱們就可使用Remove Parameter去掉discountLevel參數了:

public double getPrice(){
    int basePrice = _quantity * _itemPrice;
    int discountLevel = getDiscountLevel();
    double final Price = discountedPrice(basePrice, discountLevel);
    return finalPrice;
}

private double discountedPrice(int basePrice){
    if(getDiscountLevle() == 2){
        return basePrice * 0.1;
    }else{
        return basePrice * 0.05;
    }
}

接下來能夠將discountLevel變量去除掉:

public double getPrice(){
    int basePrice = _quantity * _itemPrice;
    double final Price = discountedPrice(basePrice);
    return finalPrice;
}

如今,能夠去掉其餘非必要的參數和相應的臨時變量。最後得到如下代碼:

public double getPrice(){
    return discountedPrice();
}

private doulbe discountedPrice(){
     if(getDiscountLevle() == 2){
        return getBasePrice() * 0.1;
    }else{
        return getBasePrice() * 0.05;
    }
}

private double getBasePrice(){
    return _quantity * _itemPrice;
}

最後,還能夠針對discountedPrice()函數使用Inline Method:

public double getPrice(){
     if(getDiscountLevle() == 2){
        return getBasePrice() * 0.1;
    }else{
        return getBasePrice() * 0.05;
    }
}
相關文章
相關標籤/搜索