首页/开发/代码质量与评审速查/手法:Combine Functions into Class / Transform
重构手法62 条

手法:Combine Functions into Class / Transform

多个函数围绕同一份数据工作:用 Combine Functions into Class 把数据与行为合并为类;处理「先输入再输出」的管道用 Combine Functions into Transform 聚为一次转换。

Combine Functions into Class 是什么

当多个函数围绕同一份数据工作、反复接收同一组参数时,把这组数据和这些函数合并进一个类,调用方就不再需要搬运参数,也不必知道中间的计算细节。若处理的是「先输入再输出」的一次性管道,则用 Combine Functions into Transform:把中间结果作为显式的中间结构在函数间传递,避免在各处重复计算。

基本信息

选择有持续状态 → Class;一次性数据变形 → Transform
效果调用方依赖减少,中间结构可以隐藏
入口先做 Encapsulate Record 把散落的字段收进对象
注意类只收容围绕同一份数据的函数

判断信号

  • 同一组参数在五个函数里反复出现,顺序还总一样
  • 中间结果被反复计算,或在多个函数里各算一遍
  • 调用方要自己记住「先调哪个再调哪个」,顺序属于调用者知识
  • 几个函数互相传递半成品结构,谁都不完整
  • 逻辑只在服务层散落,对象本身没有任何行为

类合并示意

类合并示意
// 之前:散落的函数与来回传递的 reading
base(reading), taxable(reading), total(reading)

// 之后:数据与行为聚在一起,调用方只提出意图
class Reading {
    private final ReadingData data;
    double base()    { return data.kwh * data.rate; }
    double taxable() { return base() * taxRate(); }
    double total()   { return base() + taxable(); }
}

// 调用侧
reading.total();

两种形态的选择

维度Combine into ClassCombine into Transform
数据生命周期持续存在、可复用一次流转后丢弃
中间结构封装为字段显式中间对象
典型场景领域计算、计费、报表口径导入、导出、批处理管道
测试方式对类写单测对纯函数写单测
合并的前提是「围绕同一份数据」。把调用时机不同、数据来源不同的函数硬塞进一个类,结果是类成为杂物间,随后就会出现下一轮拆分。
Transform 版本要保持纯函数:把读文件、写日志等副作用留在管道两端。一旦变形过程里混入 I/O,就很难对中间结果单独断言。

易错点

  • 把无关函数硬塞进类:类成为杂物间,职责说不清
  • Transform 里混合 I/O:纯变形与副作用纠缠,难测试
  • 只搬家不改调用方:调用点依旧传同一组参数,收益没有兑现
  • 中间结构直接暴露内部字段:调用方绕过计算逻辑自行拼装,口径再次分叉
  • 合并后忘记收敛参数:类里仍保留一组入参重载方法,新旧两套入口并存

数据来源与参考

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