目錄

  •     壞味道——過長參數(shù)列(Long Parameter List)

  •         特征

  •         問題原因

  •         解決方案

  •         收益

  •         何時忽略

  •     重構(gòu)方法說明

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

  •         保持對象完整(Preserve Whole Object)

  •         引入?yún)?shù)對象(Introduce Parameter Object)

  •     引申閱讀

壞味道——過長參數(shù)列(Long Parameter List)

特征

一個函數(shù)有超過3、4個入?yún)ⅰ?/p>

問題原因

過長參數(shù)列可能是將多個算法并到一個函數(shù)中時發(fā)生的。函數(shù)中的入?yún)⒖梢杂脕砜刂谱罱K選用哪個算法去執(zhí)行。

過長參數(shù)列也可能是解耦類之間依賴關(guān)系時的副產(chǎn)品。例如,用于創(chuàng)建函數(shù)中所需的特定對象的代碼已從函數(shù)移動到調(diào)用函數(shù)的代碼處,但創(chuàng)建的對象是作為參數(shù)傳遞到函數(shù)中。因此,原始類不再知道對象之間的關(guān)系,并且依賴性也已經(jīng)減少。但是如果創(chuàng)建的這些對象,每一個都將需要它自己的參數(shù),這意味著過長參數(shù)列。

太長的參數(shù)列難以理解,太多參數(shù)會造成前后不一致、不易使用,而且一旦需要更多數(shù)據(jù),就不得不修改它。

解決方案

  • 如果向已有的對象發(fā)出一條請求就可以取代一個參數(shù),那么你應(yīng)該使用 以函數(shù)取代參數(shù)(Replace Parameter with Methods) 。在這里,,“已有的對象”可能是函數(shù)所屬類里的一個字段,也可能是另一個參數(shù)。

  • 你還可以運用 保持對象完整(Preserve Whole Object) 將來自同一對象的一堆數(shù)據(jù)收集起來,并以該對象替換它們。

  • 如果某些數(shù)據(jù)缺乏合理的對象歸屬,可使用 引入?yún)?shù)對象(Introduce Parameter Object) 為它們制造出一個“參數(shù)對象”。

收益

  • 更易讀,更簡短的代碼。

  • 重構(gòu)可能會暴露出之前未注意到的重復(fù)代碼。

何時忽略

  • 這里有一個重要的例外:有時候你明顯不想造成"被調(diào)用對象"與"較大對象"間的某種依賴關(guān)系。這時候?qū)?shù)據(jù)從對象中拆解出來單獨作為參數(shù),也很合情理。但是請注意其所引發(fā)的代價。如果參數(shù)列太長或變化太頻繁,就需要重新考慮自己的依賴結(jié)構(gòu)了。

重構(gòu)方法說明

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

問題

對象調(diào)用某個函數(shù),并將所得結(jié)果作為參數(shù),傳遞給另一個函數(shù)。而接受該參數(shù)的函數(shù)本身也能夠調(diào)用前一個函數(shù)。

int basePrice = quantity * itemPrice;double seasonDiscount = this.getSeasonalDiscount();double fees = this.getFees();double finalPrice = discountedPrice(basePrice, seasonDiscount, fees);

解決

讓參數(shù)接受者去除該項參數(shù),并直接調(diào)用前一個函數(shù)。

int basePrice = quantity * itemPrice;double finalPrice = discountedPrice(basePrice);

保持對象完整(Preserve Whole Object)

問題

你從某個對象中取出若干值,將它們作為某一次函數(shù)調(diào)用時的參數(shù)。

int low = daysTempRange.getLow();int high = daysTempRange.getHigh();boolean withinPlan = plan.withinRange(low, high);

解決

改為傳遞整個對象。

boolean withinPlan = plan.withinRange(daysTempRange);

引入?yún)?shù)對象(Introduce Parameter Object)

問題

某些參數(shù)總是很自然地同時出現(xiàn)。

解決

以一個對象來取代這些參數(shù)。