坏味道——过长参数列(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)

问题

某些参数总是很自然地同时出现。

解决

以一个对象来取代这些参数。

引申阅读

欢迎继续阅读 代码的症与药 系列文章。

代码的坏味道(4)——过长参数列(Long Parameter List)的更多相关文章

  1. 【重构】 代码的坏味道总结 Bad Smell (一) (重复代码 | 过长函数 | 过大的类 | 过长参数列 | 发散式变化 | 霰弹式修改)

    膜拜下 Martin Fowler 大神 , 开始学习 圣经 重构-改善既有代码设计 . 代码的坏味道就意味着需要重构, 对代码的坏味道了然于心是重构的比要前提; . 作者 : 万境绝尘 转载请注明出 ...

  2. 重构 之 总结代码的坏味道 Bad Smell (一) 重复代码 过长函数 过大的类 过长参数列 发散式变化 霰弹式修改

    膜拜下 Martin Fowler 大神 , 开始学习 圣经 重构-改善既有代码设计 . 代码的坏味道就意味着需要重构, 对代码的坏味道了然于心是重构的比要前提; . 作者 : 万境绝尘 转载请注明出 ...

  3. Refactoring之——代码的坏味道(一)过长方法

    1 代码的坏味道 重构一书中提到了22种代码的坏味道,大致可以分为几类. 识别代码的坏味道,有助于发现代码的潜在问题,从而可以有的放矢的修改现有代码,使之不断完善. 1.1 Bloaters(臭鲱,暂 ...

  4. Refactoring之——代码的坏味道(四)过长参数列

    1.1.4 Long Parameter List(过长参数列) 特征:一个方法有超过三四个的参数. 问题原因: 过长参数列可能是将多个算法并到一个函数中时发生的.函数中的入参可以用来控制最终选用哪个 ...

  5. Bad Smell (代码的坏味道)

    sourcemaking 如果一段代码是不稳定或者有一些潜在问题的,那么代码往往会包含一些明显的痕迹.正如食物要腐坏之前,经常会发出一些异味一样, 我们管这些痕迹叫做 "代码异味" ...

  6. 【转】Bad Smell(代码的坏味道)

    1.Duplicated Code(重复的代码) 臭味行列中首当其冲的就是Duplicated Code.如果你在一个以上的地点看到相同的程序结构,那么当可肯定:设法将它们合而为一,程序会变得更好. ...

  7. Chapter 3 :代码的坏味道

    "如果尿布臭了,就换掉它." --Beck奶奶,论保持小孩清洁的哲学 代码的坏味道这一章集中论述该何时重构.具体的重构方法在后面的章节. "没有任何度量规矩比得上见识广博 ...

  8. 消灭 Java 代码的“坏味道”

    消灭 Java 代码的“坏味道” 原创: 王超 阿里巴巴中间件 昨天 导读 明代王阳明先生在<传习录>谈为学之道时说: 私欲日生,如地上尘,一日不扫,便又有一层.着实用功,便见道无终穷,愈 ...

  9. 代码的坏味道(7)——临时字段(Temporary Field)

    坏味道--临时字段(Temporary Field) 特征 临时字段的值只在特定环境下有意义,离开这个环境,它们就什么也不是了. 问题原因 有时你会看到这样的对象:其内某个实例变量仅为某种特定情况而设 ...

随机推荐

  1. WebServer+ADO+百万数据查询

    很简单的demo,查询速度快,易理解,废话不说  上demo 看完就明白了 源码地址:http://files.cnblogs.com/files/SpadeA/WebDemo.zip 这是关于Web ...

  2. WDM驱动和NT驱动之我见

    WDM驱动是NT驱动的进化版.我个人觉得它的主要好处有两个 1.能检测到设备的插入,系统能自动分配设备的硬件信息,如中断号.IO端口.设备物理地址等 2.支持设备的开机状态拔出 之前的NT驱动和硬件关 ...

  3. 关于IoCallDriver使用的疑惑

    #pragma PAGEDCODE NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) { KdPrint(("Dr ...

  4. Wishart distribution

    Introduction In statistics, the Wishart distribution is generalization to multiple dimensions of the ...

  5. ASP.NET Core 使用 Redis 和 Protobuf 进行 Session 缓存

    前言 上篇博文介绍了怎么样在 asp.net core 中使用中间件,以及如何自定义中间件.项目中刚好也用到了Redis,所以本篇就介绍下怎么样在 asp.net core 中使用 Redis 进行资 ...

  6. 领域驱动设计(DDD)部分核心概念的个人理解

    领域驱动设计(DDD)是一种基于模型驱动的软件设计方式.它以领域为核心,分析领域中的问题,通过建立一个领域模型来有效的解决领域中的核心的复杂问题.Eric Ivans为领域驱动设计提出了大量的最佳实践 ...

  7. 让pv3d(papervision3D)支持单帧前进、后退(nextFrame)。

    下载最新的源码,找到animationController. 修改如下: package org.papervision3d.core.controller { import flash.events ...

  8. JSON数据的定义

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. iOS --------Crash 分析(一)

    iOS Crash 分析(文一)- 开始 1. 名词解释 1. UUID 一个字符串,在iOS上每个可执行文件或库文件都包含至少一个UUID.目的是为了唯一识别这个文件. 2. dwarfdump 苹 ...

  10. tornado 学习笔记9 Tornado web 框架---模板(template)功能分析

            Tornado模板系统是将模板编译成Python代码.         最基本的使用方式: t = template.Template("<html>{{ myv ...