首页/开发/代码质量与评审速查/手法:Remove Middle Man(移除中间人)
重构手法62 条

手法:Remove Middle Man(移除中间人)

转发过多时让调用方直接与真实对象交互:中间层只剩透传就失去价值,删掉它减少调用链;先确认中间人没有校验、缓存、权限等隐式职责。

是什么

移除中间人(Remove Middle Man)处理转发过多的情形:当一个类的方法大多只是把调用原样转给另一个对象时,中间层已经没有独立价值,让调用方直接与真实对象交互即可。它与隐藏委托互为反向操作——封装与暴露之间的取舍取决于中间层是否还在承担职责。动手前的关键动作是确认中间人没有隐藏的横切职责。

识别与前置检查

信号中间类的方法大多只有一行转发
前置检查是否承担校验、埋点、权限、缓存等横切职责
做法暴露真实对象引用,删除纯转发方法
反向操作隐藏委托:调用链过长且中间层需要收拢复杂度时再包一层

典型使用场景

  • 为了封装而层层包装:三层都是转发,调用链变长,删除多余的中间层
  • 字段访问转发:为内部集合提供了完整的一组转发方法,不如直接暴露只读视图
  • 包装类只剩转调:原实现细节已稳定,包装带来的灵活性没有实际用途
  • 历史遗留的委托层:当初为隔离外部库而建,该外部库已经被替换为可控实现
  • 测试替身难写:中间层太多导致需要逐层打桩,移除后可以直接替换真实依赖

核实要点

核实要点
// 纯转发:中间层没有增加任何职责
void pay() { ledger.pay(); }

// 有职责:审计与校验发生在这里,不能直接删掉
void pay() {
    audit.log();          // 记录操作
    ledger.pay();
}

保留还是移除

中间层承担的事判断理由
只做方法转发移除没有独立职责,只是增加调用层级
参数校验与规范化保留调用方依赖这层保证,删掉会改变契约
权限判定保留安全职责分散到调用方极易出错
埋点与审计保留或显式化删除会导致可观测性或合规记录丢失
协议转换保留转换逻辑有独立变化轴,属于适配器职责
缓存与批处理保留属于性能策略,调用方不应自行实现
移除后直接暴露内部对象,调用方可能顺手修改内部状态:配合提供只读视图或不可变集合,避免把封装问题转化成数据一致性问题。
移除中间人常与内联类、隐藏委托配合使用:中间层数量多时,先逐层判断职责,再决定移除还是保留,不必一次改完所有层级。

落地检查清单

  • 删除前逐条核对被删方法是否有隐含职责
  • 暴露对象时提供只读视图,不直接交出可变内部结构
  • 调用点更新后跑一遍涉及权限与审计的测试
  • 文档中记录移除原因,避免后来者又加回中间层

易错点

  • 误删有隐式职责的转发:审计与权限校验悄然消失,问题往往在合规检查时才被发现
  • 直接暴露内部可变对象:调用方乱改内部状态,封装问题转成了数据一致性问题
  • 为了减少类数量而一次删掉多层:中间层之间的职责差异没有核对,隐藏契约被破坏
  • 保留纯转发层不管成本:调用链越来越长,调试时需要在多层之间跳转,理解成本持续累积

数据来源与参考

  • 《重构》第 2 版 · 第 7 章(Remove Middle Man)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌