目录
坏味道——过长参数列(Long Parameter List)
特征
问题原因
解决方案
收益
何时忽略
重构方法说明
以函数取代参数(Replace Parameter with Methods)
保持对象完整(Preserve Whole Object)
引入参数对象(Introduce Parameter Object)
引申阅读
坏味道——过长参数列(Long Parameter List)
特征
一个函数有超过3、4个入参。
问题原因
过长参数列可能是将多个算法并到一个函数中时发生的。函数中的入参可以用来控制最终选用哪个算法去执行。
过长参数列也可能是解耦类之间依赖关系时的副产品。例如,用于创建函数中所需的特定对象的代码已从函数移动到调用函数的代码处,但创建的对象是作为参数传递到函数中。因此,原始类不再知道对象之间的关系,并且依赖性也已经减少。但是如果创建的这些对象,每一个都将需要它自己的参数,这意味着过长参数列。
太长的参数列难以理解,太多参数会造成前后不一致、不易使用,而且一旦需要更多数据,就不得不修改它。
解决方案
如果向已有的对象发出一条请求就可以取代一个参数,那么你应该使用
以函数取代参数(Replace Parameter with Methods)
。在这里,,“已有的对象”可能是函数所属类里的一个字段,也可能是另一个参数。你还可以运用
保持对象完整(Preserve Whole Object)
将来自同一对象的一堆数据收集起来,并以该对象替换它们。如果某些数据缺乏合理的对象归属,可使用
引入参数对象(Introduce Parameter Object)
为它们制造出一个“参数对象”。
收益
更易读,更简短的代码。
重构可能会暴露出之前未注意到的重复代码。
何时忽略
这里有一个重要的例外:有时候你明显不想造成"被调用对象"与"较大对象"间的某种依赖关系。这时候将数据从对象中拆解出来单独作为参数,也很合情理。但是请注意其所引发的代价。如果参数列太长或变化太频繁,就需要重新考虑自己的依赖结构了。
重构方法说明
以函数取代参数(Replace Parameter with Methods)
问题
对象调用某个函数,并将所得结果作为参数,传递给另一个函数。而接受该参数的函数本身也能够调用前一个函数。
int basePrice = quantity * itemPrice;double seasonDiscount = this.getSeasonalDiscount();double fees = this.getFees();double finalPrice = discountedPrice(basePrice, seasonDiscount, fees);
解决
让参数接受者去除该项参数,并直接调用前一个函数。
int basePrice = quantity * itemPrice;double finalPrice = discountedPrice(basePrice);
保持对象完整(Preserve Whole Object)
问题
你从某个对象中取出若干值,将它们作为某一次函数调用时的参数。
int low = daysTempRange.getLow();int high = daysTempRange.getHigh();boolean withinPlan = plan.withinRange(low, high);
解决
改为传递整个对象。
boolean withinPlan = plan.withinRange(daysTempRange);
引入参数对象(Introduce Parameter Object)
问题
某些参数总是很自然地同时出现。
解决
以一个对象来取代这些参数。