首页/开发/代码质量与评审速查/手法:Combine Functions into Class(合并为类)
重构手法62 条

手法:Combine Functions into Class(合并为类)

函数组共享同一批参数或同一份数据时,将它们收进类:数据成为字段、函数成为方法,调用方从此只面对对象;适合把散落的计算集中成领域行为。

是什么

合并函数为类(Combine Functions into Class)针对的是一组反复接收同一批参数的函数:把这批数据变成对象的字段,把这些函数变成对象的方法,调用方从此只面对一个对象。它解决的是参数在调用链上一路传递的问题,也常常顺带把散落的计算聚成一处领域行为。若这批数据只是流经一次、用完即弃,用对应的变换变体聚合到数据结构里更轻。

识别与做法

信号多个函数反复接收同一组参数,或反复读取同一批字段
做法建类、参数变字段、函数变方法、调用点改为对对象发消息
轻量替代一次性数据管道用变换变体:把派生值直接挂到数据结构上
代价类成为新的状态载体,需明确可变性约束

典型使用场景

  • 报表计算:基础值、税额、总计三个函数都接收同一条读数记录
  • 费用规则:折扣、运费、税费函数共享同一份订单上下文
  • 解析与校验:多个步骤都要用到同一份配置参数
  • 统计聚合:多个指标计算函数都接收同一批采样数据
  • 调用方参数爆炸:一个函数需要传七个相关字段,先聚成对象再传

方向示例

方向示例
// 调整前:三个函数反复接收同一条记录
base(reading);
taxable(reading);
total(reading);

// 调整后:数据成为字段,计算成为方法
class Reading {
    private final double value;
    double base() { return value; }
    double taxable() { return value * 0.06; }
}

两种变体的选择

情形选择理由
数据存在多个变化轴、需长期演进合并为类字段可封装不变式,方法可独立测试
数据只流经一次、用完即弃变换变体(挂派生字段)不必引入新的状态载体,改动面更小
多个使用方共享同一份数据合并为类避免每处重复传递与计算
计算需要访问外部依赖保留为函数并显式注入依赖把外部依赖塞进数据对象会让对象职责变混
字段本身由多线程并发修改先解决并发模型合并后状态集中,竞态更容易被掩盖
合并的边界是数据与行为的对应关系:只有当这些函数确实围绕同一份数据工作时才合并。把不相关的工具函数也塞进同一个类,会得到一个聚合容器,可读性比原来更差。
合并后要注意字段可变性:如果字段可以被外部修改,派生计算的结果会随修改漂移。优先让字段在构造时确定,或把派生值缓存与失效策略写清楚。

落地检查清单

  • 合并后的类名能准确描述它承载的数据与行为
  • 方法之间是否真的围绕同一份数据工作
  • 字段可变性有明确约束,派生计算不会静默漂移
  • 调用点的参数数量明显减少,阅读时不必再对照参数表

易错点

  • 把不相关的工具函数硬塞进领域类:类变成聚合容器,命名说不清职责,新人不敢改
  • 字段可变且被多处修改:行为合并后状态变化路径变多,调试时难以确定是哪一步改了值
  • 对一次性数据管道也建类:增加了一层生命周期管理,收益却只有参数变少
  • 合并后忘记收敛可见性:字段被外部直接读写,封装形同虚设

数据来源与参考

  • 《重构》第 2 版 · 第 6 章(Combine Functions into Class)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌