目錄
壞味道——過長參數(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ù)。