首页/开发/代码质量与评审速查/坏味道:过长参数列表(Long Parameter List)
重构手法62 条

坏味道:过长参数列表(Long Parameter List)

参数过多表示函数依赖面过宽:把成组参数换成对象(Introduce Parameter Object)、把查询替换为对象方法(Replace Parameter with Query)、移除多余参数。

过长参数列表是什么

参数过多意味着函数的依赖面太宽:调用时要记住顺序与含义,改动时牵一发动全身。常见信号是四个以上参数,或者多个参数总是成对出现,比如起始时间与结束时间。常用处理手法包括引入参数对象、保持对象完整,以及去掉标志位参数。

基本信息

识别信号四个以上参数,或参数之间总是结伴出现
常用手法引入参数对象、保持对象完整、去掉标志位参数
配套检查多数检查工具都有参数数量的提示规则
注意提取出来的参数对象应当有自己的行为

典型使用场景

  • 查询函数参数越加越多:把条件聚合成查询对象
  • 布尔标志位当开关:一拆为二,或改用两个具名方法
  • 参数总是成对出现:说明它们本来就属于同一个概念
  • 传递整个对象却只用一个字段:改为传该字段,或保持对象完整
  • 重构中间态:先用参数对象过渡,后续继续搬移职责

提取参数对象的步骤

  • 找出一组总是同时出现的参数
  • 为这组参数命名,名字体现业务含义
  • 把参数替换为对象,并让对象承担相关校验
  • 检查调用点,确认语义仍然清晰

前后对比

前后对比
// 之前:六个参数,顺序很容易传错
void render(String name, int age, String dept, String title, long id, boolean active) { ... }

// 之后:一组参数收敛为一个对象
void render(Employee employee) { ... }

手法对照

手法适用情况
引入参数对象多个参数总是成组出现
保持对象完整调用方本来就有这个对象,只是拆开传了字段
去掉标志位参数布尔参数决定两套行为
参数对象不要沦为数据袋:把校验与格式化这类行为放进去,否则只是把参数挪了个位置。
调用点最容易暴露问题:同一个调用连续传进五个字面量,说明这组参数本来就应该有个名字。

易错点

  • 顺序相近类型的参数(两个整数):调用处极容易传反,编译期还查不出来
  • 引入参数对象后直接暴露所有字段:封装形同虚设
  • 为减少参数数量把状态塞进类字段:无状态函数变成有状态,并发下更危险
  • 标志位参数长期保留:函数内部两套行为交织,测试与维护成本翻倍

数据来源与参考

  • 《重构》第 2 版 · 第 3 章(Long Parameter List)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌